7. subprocess
一、介绍
subprocess模块可以生成新的进程,连接到它们的input/output/error管道,同时获取它们的返回码。
二、基本操作方法
1. subprocess的run、call、check_call、check_output函数
subprocess.run(args[, stdout, stderr, shell ...]):执行args命令,返回值为CompletedProcess类;
若未指定stdout,则命令执行后的结果输出到屏幕上,函数返回值CompletedProcess中包含有args和returncode;
若指定有stdout,则命令执行后的结果输出到stdout中,函数返回值CompletedProcess中包含有args、returncode和stdout;
若执行成功,则returncode为0;若执行失败,则returncode为1;
若想获取args命令执行后的输出结果,命令为:output = subprocess.run(args, stdout=subprocess.PIPE).stdoutsubprocess.call(args[, stdout, ...]):执行args命令,返回值为命令执行状态码;
若未指定stdout,则命令执行后的结果输出到屏幕;
若指定stdout,则命令执行后的结果输出到stdout;
若执行成功,则函数返回值为0;若执行失败,则函数返回值为1;
(类似os.system)subprocess.check_call(args[, stdout, ...]):执行args命令,返回值为命令执行状态码;
若未指定stdout,则命令执行后的结果输出到屏幕;
若指定stdout,则命令执行后的结果输出到stdout;
若执行成功,则函数返回值为0;若执行失败,抛出异常;
(类似subprocess.run(args, check=True))subprocess.check_output(args[, stderr, ...]):执行args命令,返回值为命令执行的输出结果;
若执行成功,则函数返回值为命令输出结果;若执行失败,则抛出异常;
(类似subprocess.run(args, check=True, stdout=subprocess.PIPE).stdout)
(1) args:启动进程的参数,默认为字符串序列(列表或元组),也可为字符串(设为字符串时一般需将shell参数赋值为True);
(2) shell:shell为True,表示args命令通过shell执行,则可访问shell的特性;
(3) check:check为True时,表示执行命令的进程以非0状态码退出时会抛出;subprocess.CalledProcessError异常;check为False时,状态码为非0退出时不会抛出异常;
(4) stdout、stdin、stderr:分别表示程序标准标输出、输入、错误信息;run函数返回值为CompletedProcess类,若需获取执行结果,可通过获取返回值的stdout和stderr来捕获;
check_output函数若需捕获错误信息,可通过stderr=subprocess.STDOUT来获取;# subprocess.run使用 def subprocess_run():print("**** subprocess.run ****")print("----------")result1 = subprocess.run(["adb", "devices"])print("result1:", result1)print("----------")result2 = subprocess.run("adb devices", shell=True, check=True)print("result2:", result2)print("----------")result3 = subprocess.run(["adb", "devices"], stdout=subprocess.PIPE)print("result3:", result3)print(type(result3)) subprocess_run() """结果 **** subprocess.run **** ---------- List of devices attached 338b123f0504 deviceresult1: CompletedProcess(args=['adb', 'devices'], returncode=0) ---------- List of devices attached 338b123f0504 deviceresult2: CompletedProcess(args='adb devices', returncode=0) ---------- result3: CompletedProcess(args=['adb', 'devices'], returncode=0, stdout=b'List of devices attached \r\n338b123f0504\tdevice\r\n\r\n') <class 'subprocess.CompletedProcess'> """# subprocess.call使用 def subprocess_call():print("**** subprocess.call ****")print("----------")result1 = subprocess.call(["adb", "devices"])print("result1:", result1)print("----------")result2 = subprocess.call(["adb", "devices"], stdout=subprocess.PIPE)print("result2:", result2) subprocess_call() """结果 **** subprocess.call **** ---------- List of devices attached 338b123f0504 deviceresult1: 0 ---------- result2: 0 """# subprocess.check_call def subprocess_check_call():print("**** subprocess.check_call ****")print("----------")result1 = subprocess.check_call(["adb", "devices"])print("result1:", result1)print("----------")result2 = subprocess.check_call(["adb", "devices"], stdout=subprocess.PIPE)print("result2:", result2) subprocess_check_call() """结果 **** subprocess.check_call **** ---------- List of devices attached 338b123f0504 deviceresult1: 0 ---------- result2: 0 """# subprocess.check_output def subprocess_check_output():print("**** subprocess.check_output ****")print("----------")result1 = subprocess.check_output(["adb", "devices"])print("result1:", result1)print("----------")result2 = subprocess.run(["adb", "devices"], stdout=subprocess.PIPE).stdoutprint("result2:", result2) subprocess_check_output() """结果 **** subprocess.check_output **** ---------- result1: b'List of devices attached \r\n338b123f0504\tdevice\r\n\r\n' ---------- result2: b'List of devices attached \r\n338b123f0504\tdevice\r\n\r\n' """
2. subprocess的getoutput、getstatusoutput函数
subprocess.getoutput(cmd):执行cmd命令,返回值为命令执行的输出结果(字符串类型);
注:执行失败,不会抛出异常(类似os.popen(cmd).read());subprocess.getstatusoutput(cmd):执行cmd命令,返回值为元组类型(命令执行状态, 命令执行的输出结果);
元组中命令执行状态为0,表示执行成功;命令执行状态为1,表示执行失败;
cmd:参数,字符串类型;
# subprocess.getoutput或getstatusoutput使用
def subprocess_get_output():print("**** subprocess.getoutput ****")result1 = subprocess.getoutput("adb devices")print("result1:", result1)print(type(result1))print("**** subprocess.getstatusoutput ****")result2 = subprocess.getstatusoutput("adb devices")print("result2:", result2)print(type(result2))
subprocess_get_output()
"""结果
**** subprocess.getoutput ****
result1: List of devices attached
338b123f0504 device<class 'str'>
**** subprocess.getstatusoutput ****
result2: (0, 'List of devices attached \n338b123f0504\tdevice\n')
<class 'tuple'>
"""
三、 subprocess.Popen类
1. 介绍
subprocess.Popen类用于在一个新进程中执行一个子程序,上述subprocess函数均是基于subprocess.Popen类;
2.操作
- subprocess.Popen(args[, bufsize, stdin, stdout, stderr, ...]):Popen类的构造函数,返回结果为subprocess.Popen对象;
- args:需要执行的系统命令,可为字符串序列(列表或元组,shell为默认值False即可,建议为序列),也可为字符串(使用字符串时,需将shell赋值为True);
- shell:默认为False,若args为序列时,shell=False;若args为字符串时,shell=True,表示通过shell执行命令;
- stdout、stdin、stderr:分别表示子程序标准输出、标准输入、标准错误,可为subprocess.PIPE、一个有效的文件描述符、文件对象或None。
若为subprocess.PIPE:代表打开通向标准流的管道,创建一个新的管道;
若为None:表示没有任何重定向,子进程会继承父进程;
stderr也可为subprocess.STDOUT:表示将子程序的标准错误输出重定向到了标准输出- bufsize:指定缓冲策略,0表示不缓冲,1表示行缓冲,其它整数表示缓冲区大小,负数表示使用系统默认值0;
- cwd:默认值为None;若非None,则表示将会在执行这个子进程之前改变当前工作目录;
- env:用于指定子进程的环境变量。若env为None,那么子进程的环境变量将从父进程中继承;若env非None,则表示子程序的环境变量由env值来设置,它的值必须是一个映射对象。
- universal_newlines: 不同系统的换行符不同。若True,则该文件对象的stdin,stdout和stderr将会以文本流方式打开;否则以二进制流方式打开。
(1)subprocess.Popen对象常用方法(如PopenObject为subprocess.Popen对象)
- PopenObject.poll() :用于检查命令是否已经执行结束,若结束返回状态码;若未结束返回None;
- PopenObject.wait([timeout, endtime]):等待子进程结束,并返回状态码;若超过timeout(s)进程仍未结束,则抛出异常;
- PopenObject.send_signal(signal):发送信号signal给子进程;
- PopenObject.terminate():停止子进程;
- PopenObject.kill():杀死子进程;
- PopenObject.communicate([input, timeout]):与进程进行交互(如发送数据到stdin、读取stdout和stderr数据),它会阻塞父进程,直到子进程完成;
input:表示将发送到子进程的字符串数据,默认为None;
timeout:超时判断,若超过timeout秒后仍未结束则抛出TimeoutExpired异常;
communicate返回值:一个元组(stdout_data, stderr_data)
(2)subprocess.Popen对象的文本或字节流控制
PopenObject.stdin:
若PopenObject中stdin为PIPE,则返回一个可写流对象;若encoding或errors参数被指定或universal_newlines参数为True,则此流是一个文件流,否则为字节流。
若PopenObject中stdin不是PIPE,则属性为None。
stdin输入流非None,可执行写操作即PopenObject.stdin.write(s)PopenObject.stdout:
若PopenObject中stdout为PIPE,则返回一个可读流对象;若encoding或errors参数被指定或universal_newlines参数为True,则此流是一个文件流,否则为字节流。
若PopenObject中stdout不是PIPE,则属性为None。
stdout输出流非None,可执行读操作即PopenObject.stdout.read()或.readlines()PopenObject.stderr:
若PopenObject中stderr为PIPE,则返回一个可读流对象;若encoding或errors参数被指定或universal_newlines参数为True,则此流是一个文件流,否则为字节流。
若PopenObject中stderr不是PIPE,则属性为None。
stderr错误流非None,可执行读操作即PopenObject.stderr.read()或.readlines()def subprocess_Popen1():print("***通过communicate函数分别输出PopenObject对象的输出流和错误流***")args = [["adb", "devices"], ["adb", "devices11"]]for arg in args:popen_object = subprocess.Popen(arg, stdout=subprocess.PIPE, stderr=subprocess.PIPE)object_stdout, object_stderr = popen_object.communicate()output = {"popen_object": popen_object,"object_stdout": object_stdout,"object_stderr": object_stderr}print(output)"""{'popen_object': <subprocess.Popen object at 0x0000000002212400>, 'object_stdout': b'List of devices attached \r\n106D111805005938\tdevice\r\n\r\n', 'object_stderr': b''}{'popen_object': <subprocess.Popen object at 0x0000000002577C18>, 'object_stdout': b'', 'object_stderr': b'Android Debug Bridge version 1.0.31\r\n\r\n -a .....}"""print("***通过stdout和stderr方法输出PopenObject对象输出流和错误流***")p0 = subprocess.Popen(["adb", "devices"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)object_stdout = p0.stdout.read()p0.stdout.close()object_stderr = p0.stderr.read()p0.stderr.close()print(object_stdout) # 结果:b'List of devices attached \r\n338b123f0504\tdevice\r\n\r\n'print(object_stderr) # 结果:b''print("***Popen对象stdin写入功能:使用stdout和stderr输出")args = ["python", "python1"]for arg in args:p4 = subprocess.Popen([arg], shell=True, stdout=subprocess.PIPE,stdin=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)p4.stdin.write("print('hello')")p4.stdin.close()out = p4.stdout.read()p4.stdout.close()err = p4.stderr.read()p4.stderr.close()print("out:%s err:%s" % (out, err))"""***Popen对象stdin写入功能out:helloerr:out: err:'python1' 不是内部或外部命令,也不是可运行的程序或批处理文件。"""print("***Popen对象stdin写入功能:使用communicate输出")p4 = subprocess.Popen(["python"], stdout=subprocess.PIPE,stdin=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)p4.stdin.write("print('hello')")output = p4.communicate()print(output) # 结果:('hello\n', '')print("***不含encoding参数***")p1 = subprocess.Popen("adb devices", shell=True, stdout=subprocess.PIPE)out1 = p1.stdout.readlines()print(out1) # 结果: [b'List of devices attached \r\n', b'106D111805005938\tdevice\r\n', b'\r\n']print("***含encoding参数***")p2 = subprocess.Popen("adb devices", shell=True, stdout=subprocess.PIPE, encoding="utf-8")out2 = p2.stdout.readlines()print(out2) # 结果: ['List of devices attached \n', '106D111805005938\tdevice\n', '\n']print("***Popen对象检查命令是否结束,等待进程结束")print(p2.poll()) # 结果: Noneprint(p2.wait()) # 结果: 0print(p2.poll()) # 结果: 0print("***Popen对象communicate函数,它会阻塞父进程直至子进程完成")p3 = subprocess.Popen("adb devices", shell=True, stdout=subprocess.PIPE)out = p3.communicate()[0]print(out) # 结果:b'List of devices attached \r\n338b123f0504\tdevice\r\n\r\n'print(p3.poll()) # 结果:0 subprocess_Popen1()def subprocess_Popen2():"""1. 通过管道功能,实现adb shell ps | findstr top功能2. 直接为args赋值为一个字符串,实现adb shell ps | findstr top功能:return:"""print("***通过管道方式***")p1 = subprocess.Popen(["adb", "shell", "ps"], stdout=subprocess.PIPE)p2 = subprocess.Popen(["findstr", "top"], stdin=p1.stdout, stdout=subprocess.PIPE, stderr=subprocess.PIPE)out, err = p2.communicate()print(out, err) # 结果:b'shell 8508 8504 2600 1044 c004e5f8 b6f40938 S top\r\r\n' b''print("***通过传一个字符串方式***")p3 = subprocess.Popen("adb shell ps | findstr top", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)out, err = p3.communicate()print(out, err) # 结果:b'shell 8508 8504 2600 1044 c004e5f8 b6f40938 S top\r\r\n' b'' subprocess_Popen2()
7. subprocess相关推荐
- python subprocess_python subprocess
subprocess.call() 执行命令,并返回执行状态,其中shell参数为False时,命令需要通过列表的方式传入,当shell为True时,传入命令字符串.默认为False a = subp ...
- python popen阻塞_对Python subprocess.Popen子进程管道阻塞详解
问题产生描述 使用子进程处理一个大的日志文件,并对文件进行分析查询,需要等待子进程执行的输出结果,进行下一步处理. 出问题的代码 # 启用子进程执行外部shell命令 def __subprocess ...
- 【错误归纳】E: Sub-process /usr/bin/dpkg returned an error code (1)子进程 已安装 post-installation 脚本 返回了错误号 1
问题描述 我在使用apt-get install 安装某个程序的时候出现了下面的错误提示: 正在设置 anydesk (5.1.1) ...System start/stop links for /e ...
- python subprocess库 终端命令行命令
python subprocess subprocess 模块允许我们启动一个新进程,并连接到它们的输入/输出/错误管道,从而获取返回值. 具体看官方文档 https://docs.python.or ...
- subprocess模块
subprocess 转载于:https://www.cnblogs.com/MeiCheng/p/10195515.html
- Python调用外部程序——os.system()和subprocess.call()
通过os.system和subprocess.call()函数调用其他程序 预备知识:cmd中打开和关闭程序 cmd中打开程序 a.打开系统自带程序 系统自带的程序的路径一般都已加入环境变量之中,只需 ...
- 使用pyinstaller打包,subprocess报“句柄无效”错误的解决方法
2019独角兽企业重金招聘Python工程师标准>>> 使用pyinstaller打包python程序,使用-w参数,去掉console,发现执行命令行的subprocess相关语句 ...
- subprocess 的 kill()/terminate() 问题
虽然 python2.6中的subprocess模块增加了 kill() terminate() 来控制子进程退出 但是在实际的使用过程中会发现 如果子进程并不是自己退出,而是调用 kill() ...
- 第四十四节,subprocess系统命令模块
用python执行系命令的相关的模块和函数的功能均在 subprocess 模块中实现,并提供了丰富的功能 call()模块函数 功能:输入系统命令,直接执行命令,返回状态码,只能查看[有参] 使用方 ...
- python3 subprocess_Python 3.4.3 subprocess.Popen获取命令输出而不管道?
使用pexpect: 2.py: import sys if sys.stdout.isatty(): print('hello') else: print('goodbye') 子: import ...
最新文章
- cuda 0 not supported xla
- tcpdump的简单选项介绍
- GitHub上最受欢迎的Android开源项目TOP20
- 产品经理经验谈:从产品经理、用户、产品的角度重新认知产品运营
- android自带的nsd发现服务器,Android网络服务发现(NSD)协议的使用
- 选32位 64位 oracle,32位PLSQL配置为64位的Oracle和64位系统
- shownews.php,newsshow.php
- ​如何成为一个更好的 React 开发者?
- 在系统二进制文件中检测到错误_门禁管理系统施工中常见的布线错误
- NOIP2011 D1 T2选择客栈
- java response文件流下载,后缀名称设置
- 我的Android进阶之旅------百度地图学习:BDLocation.getLocType ( )值分析
- 数据结构考研复试、面试 ——常见提问总结
- 小米8刷官方欧版rom并从国内版rom提取安装MiPay、门卡模拟
- Atitit 衡量项目的规模 1. 预估衡量项目的规模的方法	1 1.1. 方法一、Delphi 法	1 1.2. 方法二、 类比法	1 1.3. 方法三、功能点估计法	2 1.4. 方法四、PER
- 高效能人士的七个习惯(二)七个习惯概论
- 怎么让台式计算机散发wifi,怎样能让台式电脑发出WIFI信号?
- 超 82% 的 GitHub 代码是重复的,还不是 Forked 而来。
- 理解单调栈与单调队列
- 喜迎国庆中秋,双节快乐!
热门文章
- 微软预告:下一代 Windows 将很快宣布
- torch.addcdiv 和 torch.tensor.addcdiv_
- Qt多功能计算器(三)——进制转换
- Android开发者选项 介绍
- 罕见病、新药最新研究进展(2021年9月)
- 大数据笔记8—java基础篇4(面向对象-封装-继承-多态)
- Q4营收远超市场预期,唯品会回归“百亿美元大户”躲过倒春寒?
- 【无标题】关于Java——给即将开学的弟弟送上一份礼物
- OneHZ Math of Rapid Calculation
- 制作CentOS 6.4 U盘启动安装盘