摘要:主要用来取代一些旧的模块方法,如等通过子进程来执行外部指令,并通过管道,获取子进程的执行的返回信息。等待子进程结束。
subprocess
subprocess模块是python从2.4版本开始引入的模块。主要用来取代 一些旧的模块方法,如os.system、os.spawn、os.popen、commands.*等subprocess通过子进程来执行外部指令,并通过input/output/error管道,获取子进程的执行的返回信息。
使用方法:
运行外部命令:subprocess.call(command)
subprocess的call方法可以用于执行一个外部命令,但该方法不能返回执行的结果,只能返回执行的状态码: 成功(0) 或 错误(非0)
方法一:
subprocess.call(["ls","-l"]) 总用量 4 -rw-r--r-- 1 liangml liangml 0 3月 7 15:38 mark.md -rw-r--r-- 1 liangml liangml 68 3月 11 13:39 php-fpm.py 0
方法二:
subprocess.call("ls -l",shell=True) 总用量 4 -rw-r--r-- 1 liangml liangml 0 3月 7 15:38 mark.md -rw-r--r-- 1 liangml liangml 68 3月 11 13:39 php-fpm.py 0
上面示例是在终端中运行,虽然可以看到运行结果,但实际取值只是状态码
a = subprocess.call("ls -l",shell=True) 总用量 4 -rw-r--r-- 1 liangml liangml 0 3月 7 15:38 mark.md -rw-r--r-- 1 liangml liangml 81 3月 11 13:44 php-fpm.py print(a) 0
错误处理:subprocess.check_call()
我们说过call执行返回一个状态码,我们可以通过check_call()函数来检测命令的执行结果,如果不成功将返回 subprocess.CalledProcessError 异常
示例:
import subprocess try: subprocess.check_call("sdf",shell=True) except subprocess.CalledProcessError as err: print("Command Error",err)
捕获输出结果:subprocess.check_output()
call()方法启动的进程,其标准输入输出会绑定到父进程的输入和输出。调用程序无法获取命令的输出结果。但可以通过check_output()方法来捕获输出。
示例:
output = subprocess.check_output("ls -l",shell=True) print(output.decode("utf-8"))
import subprocess try: output = subprocess.check_output("lT -l",shell=True,stderr=subprocess.STDOUT) except subprocess.CalledProcessError as err: print("Command Error",err) #执行结果 Command Error Command "lT -l" returned non-zero exit status 127
直接处理管道:subprocess.Popen()
函数call(), check_call() 和 check_output() 都是Popen类的包装器。直接使用Popen会对如何运行命令以及如何处理其输入输出有更多控制。如通过为stdin, stdout和stderr传递不同的参数。
与进程的单向通信:通过Popen()方法调用命令后执行的结果,可以设置stdout值为PIPE,再调用communicate()获取结果,返回结果为tuple. 在python3中结果为byte类型,要得到str类型需要decode转换一下
输出结果(读)
# 直接执行命令输出到屏幕 >>> subprocess.Popen("ls -l",shell=True)总用量 4 -rw-r--r-- 1 liangml liangml 0 3月 7 15:38 mark.md -rw-r--r-- 1 liangml liangml 76 3月 11 13:59 php-fpm.py # 不输出到屏幕,输出到变量 >>> proc = subprocess.Popen(["echo",""Stdout""],stdout=subprocess.PIPE) # communicate返回标准输出或标准出错信息 >>> stdout_value = proc.communicate() >>> stdout_value (b""Stdout" ", None) >>> proc = subprocess.Popen(["ls","-l"],stdout=subprocess.PIPE) >>> stdout_value = proc.communicate() >>> stdout_value (b"xe6x80xbbxe7x94xa8xe9x87x8f 48 drwxr-xr-x 3 liangml liangml 4096 3xe6x9cx88 10 14:57 Desktop drwxr-xr-x 6 liangml liangml 4096 3xe6x9cx88 4 22:00 Documents drwxr-xr-x 2 liangml liangml 4096 3xe6x9cx88 8 18:32 Downloads drwxr-xr-x 3 liangml liangml 4096 3xe6x9cx88 3 11:10 GitBook drwxr-xr-x 3 liangml liangml 4096 2xe6x9cx88 22 17:52 Music drwxr-xr-x 3 liangml liangml 4096 2xe6x9cx88 22 17:48 Pictures drwxr-xr-x 3 liangml liangml 4096 2xe6x9cx88 26 18:29 PycharmProjects drwxr-xr-x 3 liangml liangml 4096 2xe6x9cx88 22 18:01 Steam drwxr-xr-x 10 liangml liangml 4096 2xe6x9cx88 27 11:21 svn drwxr-xr-x 2 liangml liangml 4096 2xe6x9cx88 22 17:48 Templates drwxr-xr-x 2 liangml liangml 4096 2xe6x9cx88 22 17:24 Videos drwxr-xr-x 3 liangml liangml 4096 3xe6x9cx88 7 21:00 vnote_notebooks ", None) # 结果输出到文件 >>> file_handle = open("/home/liangml/t.log","w+") >>> subprocess.Popen("ls -l",shell=True,stdout=file_handle) >>> subprocess.call("ls -l",shell=True) 总用量 52 -rw-r--r-- 1 liangml liangml 779 3月 11 14:14 t.log vnote_notebooks
与进程的双向通信
proc = subprocess.Popen("cat", shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE) msg = "hello world".encode("utf-8") # 写入到输入管道 proc.stdin.write(msg) 11 # 输入结果 stdout_value = proc.communicate() stdout_value (b"hello world", None) # 输出结果 # 在需要进行相互交互的输入输出过程也可以使用shtin来实现 # 以下实现打开python3的终端,执行一个print命令 proc = subprocess.Popen(["python3"],stdin=subprocess.PIPE,stdout=subprocess.PIPE, stderr=subprocess.PIPE,) proc.stdin.write("print("helloworld")".encode("utf-8")) out_value,err_value=proc.communicate() print(out_value) b"helloworld " print(err_value) b""
Popen.communicate()方法用于和子进程交互:发送数据到stdin,并从stdout和stderr读数据,直到收到EOF。等待子进程结束。
捕获错误输出
proc = subprocess.Popen(["python3"],stdin=subprocess.PIPE,stdout=subprocess.PIPE, stderr=subprocess.PIPE,) proc.stdin.write("print "helloworld"".encode("utf-8")) 18 out_value,err_value=proc.communicate() out_value b"" print(err_value.decode("utf-8")) File "", line 1 print "helloworld" ^ SyntaxError: Missing parentheses in call to "print"
Popen其他方法
Popen.pid 查看子进程ID
Popen.returncode 获取子进程状态码,0表示子进程结束,None未结束
在使用Popen调用系统命令式,建议使用communicate与stdin进行交互并获取输出(stdout),这样能保证子进程正常退出而避免出现僵尸进程:
示例:
proc = subprocess.Popen("ls -l", shell=True, stdout=subprocess.PIPE) # 当前子进程ID proc.pid 5919 # 返回状态None,进程未结束 print(proc.returncode) None # 通过communicate提交后 out_value = proc.communicate() proc.pid 5919 # 返回状态为0,子进程自动结束 print(proc.returncode) 0
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/44602.html
摘要:问题如何执行外部命令,如解决方案使用库在之前,使用函数在及之后,使用函数讨论命令的执行默认不需要环境,所以当你使用作为参数时,需要将置位,否则会报错误通常来说对于执行系统命令,我们会想到,但在官方文档中已经建议了使 问题 如何执行外部命令,如ls -l 解决方案 使用subprocess库 在Python 3.5之前,使用subprocess.call()函数 >>> import s...
摘要:以前我一直用处理一些系统管理任务因为我认为那是运行命令最简单的方式我们能从官方文档里读到应该用模块来运行系统命令模块允许我们创建子进程连接他们的输入输出错误管道,还有获得返回值。模块打算来替代几个过时的模块和函数,比如命令。 以前我一直用os.system()处理一些系统管理任务,因为我认为那是运行linux命令最简单的方式.我们能从Python官方文档里读到应该用subprocess...
摘要:原因很简单,因为中的代表的就是当前执行的模块名。缺点就是主程序会受待执行程序的影响,会出现待执行程序中抛异常或主动退出会导致主程序也退出的尴尬问题。总结来说就是,一个是在子进程中执行代码,一个是在当前进程中执行代码。 showImg(https://segmentfault.com/img/remote/1460000018607395?w=502&h=318); 相信刚接触Pytho...
摘要:单元素元祖这是整数这才是元祖也许这两行,你们当时疑惑过,并且现在也都知道了,当然重点并不在这里。。虽然我水平很垃圾,但是我知道匿名函数有一种执行方式叫做自执行。看吧,这就是版的匿名函数自执行方法。 单元素元祖: a = (1) # 这是整数1 a = (1,) # 这才是元祖 也许这两行,你们当时疑惑过,并且现在也都知道了,当然重点并不在这里。。 我无聊的时候想过,为什么单...
摘要:可以执行命令的相关模块和函数有废弃废弃废弃,中被移除以上执行命令的相关的模块和函数的功能均在模块中实现,并提供了更丰富的功能。所以不能将设置为同时重定向子进程的标准输入输出与错误。同上用于设置子进程的当前目录用于指定子进程的环境变量。 可以执行shell命令的相关模块和函数有: os.system os.spawn os.popen --废弃 popen --废弃...
阅读 2040·2023-04-25 14:50
阅读 2920·2021-11-17 09:33
阅读 2625·2019-08-30 13:07
阅读 2850·2019-08-29 16:57
阅读 917·2019-08-29 15:26
阅读 3562·2019-08-29 13:08
阅读 2003·2019-08-29 12:32
阅读 3398·2019-08-26 13:57