subprocess subprocess模块是python从2.4版本开始引入的模块。主要用来取代 一些旧的模块方法,如os.system、os.spawn、os.popen、commands. subprocess try: subprocess.check_call("sdf",shell=True) except subprocess.CalledProcessError as try: output = subprocess.check_output("lT -l",shell=True,stderr=subprocess.STDOUT) except subprocess.CalledProcessError (['python3'],stdin=subprocess.PIPE,stdout=subprocess.PIPE, stderr=subprocess.PIPE,) proc.stdin.write( 捕获错误输出 proc = subprocess.Popen(['python3'],stdin=subprocess.PIPE,stdout=subprocess.PIPE, stderr=subprocess.PIPE
从Python 2.4开始,Python引入subprocess模块来管理子进程,以取代一些旧模块的方法:如 os.system、os.spawn*、os.popen*、popen2. 常用subprocess方法示例: #执行命令,返回执行状态,0或非0 >>> res = subprocess.call(["df","-h"]) Filesystem Size Used /data /dev/sdb 1.8T 696G 1.1T 40% /wdc >>> res 0 #接收字符串命令,返回元组形式,第一个元素是执行状态,第二个是执行结果 >>> subprocess.getstatusoutput sda3 91G 29G 58G 33% /data\n/dev/sdb 1.8T 696G 1.1T 40% /wdc\n' #上面那些方法,底层都是封装的subprocess.Popen #例子 >>> p = subprocess.Popen("df -h",stdin=subprocess.PIPE,stdout=subprocess.PIPE,shell=True) >>> p.stdout.read
最近在项目中有使用 subprocess 这个模块,它的功能主要是fork一个子进程,并且运行一个外部的程序。说白了就是可以用这个模块可以根据输入的字符串执行对应的系统 shell 指令。 subprocess模块中只定义了一个类: Popen。可以使用Popen来创建进程,并与进程进行复杂的交互。 它的构造函数如下: subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn subprocess.PIPE 表示一个可以被用于Popen的stdin 、stdout 和stderr 3个参数的特输值,表示需要创建一个新的管道。 subprocess.STDOUT 表示一个可以被用于 Popen 的 stderr 参数的输出值,表示子程序的标准错误汇合到标准输出。
一、subprocess模块 1.subprocess以及常用的封装函数 运行python的时候,我们都是在创建并运行一个进程。 subprocess.call() 父进程等待子进程完成 返回退出信息(returncode,相当于Linux exit code) subprocess.check_call() 父进程等待子进程完成 /usr/bin/env python import subprocess try: subprocess.check_call("exit 1",shell=True) except subprocess.CalledProcessError /usr/bin/env python import subprocess child = subprocess.Popen(["ls","-l"],stdout=subprocess.PIPE) print /usr/bin/env python import subprocess child1 = subprocess.Popen(["cat","/etc/passwd"],stdout=subprocess.PIPE
Subprocess报FileNotFoundError 代码如下: 运行时报错,FileNotFoundError: pipenv 解决方案: 因为pipenv找不到,所以需要指定全路径 pipenv # 结果显示 /root/anaconda3/bin/pipenv # 因此修改代码中pipenv为全路径的,可成功运行 另外,报FileNotFoundError 的错误,有的有可以通过在subprocess.Popen
该模块拥有多个方法,具体如下: subprocess.call() 直接打印系统命令的执行结果,如果执行成功,返回状态码为0,否则为1,例如: #执行成功 import subprocess CALL1 直接打印系统命令的执行结果,使用方法与subprocess.call()相同,只不过该函数会检测返回状态码,如果为1,则会抛出subprocess.CalledProcessError错误,例如: import subprocess # 执行成功 # CHECK_CALL1 = subprocess.check_call('ping 127.0.0.1 -n 1',shell=True) # print(CHECK_CALL1 错误,例如: import subprocess #执行成功 CHECK_OUTPUT1 = subprocess.check_output('ping 127.0.0.1 -n 1',shell=True =subprocess.PIPE) STDOUT2 = POPEN2.stdout # print(str(STDOUT2.read(),'gbk')) POPEN3 = subprocess.Popen
所以以后跟系统交互的命令,尽量用subprocess 建议调用subprocess的run()方法去跟系统进行调用,更高级的方法,使用popen() ;run()方法其实就是封装的popen。 run()方法在python3.5才有,python2.x没有,2.x用subprocess.call(),当然python3.X版本也支持call() 常见的subprocess方法 subprocess.call subprocess.call("df -lh",shell=True) 或者 subprocess.call(["df","-lh"]) 如果想获取到执行内容: a = subprocess.Popen("df -lh",shell=True,stdout=subprocess.PIPE) a.stdout.read() subprocess.check_call obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE
如果由subprocess去执行系统命令的时候并不会让主进程去执行,而是主进程会开辟出一个子进程去执行,并不会影响到主进程的运行,主进程该干嘛就干嘛,那么又有个问题,大家都知道进程之间的内存空间是独立的 subprocess基本工作原理: ? subprocess简单案例 import subprocess # 创建一个子进程去执行系统命令 obj=subprocess.Popen( 'ps -ef', # 执行的系统命令 (必须是字符串格式) shell=True, # 指定命令解释器来解释执行的这条命令 stdout=subprocess.PIPE, # 将执行的正确结果丢到管道(共享内存空间 ,用于进程之间共享) stderr=subprocess.PIPE # 将执行的错误结果丢到另一个新的管道 ) ''' 当从任意一个管道,例如正确或者错误结果管道中获取值, ''' # 从正确管道中获取值
.* 关于subprocess模块可以用来取代这些模块和功能在下面可以找到 这个模块定义了一个Popen的类: class Popen(args, bufsize=0, executable=None, 空值表示进程还没有结束,一个负值‘-N’表示子进程被信号N所结束(仅unix支持) 用subprocess模块取代旧函数: ======================================= 注意: 如果没有找到执行程序,所有在本节中的函数都有可能以静默状态失败;这个模块会抛出OSError异常 在以下的例子中, 我们假设subprocess 模块是"from subprocess import , except that: * subprocess.Popen raises an exception if the execution fails * the capturestderr * popen2 closes all filedescriptors by default, but you have to specify close_fds=True with subprocess.Popen
你可以直接在Python脚本中导入它: pythonCopy codeimport subprocess subprocess.run() subprocess.run()是Subprocess库的主要函数之一 以下是一个简单的例子: pythonCopy codeimport subprocess result = subprocess.run(['ls', '-l'], stdout=subprocess.PIPE 使用Popen类 除了subprocess.run()外,Subprocess库还提供了subprocess.Popen类,它允许更细粒度地控制子进程的输入、输出和行为。 使用Subprocess执行外部命令 Subprocess库还提供了一个名为subprocess.call()的函数,用于执行外部命令。 codeimport subprocess with subprocess.Popen(['echo', 'Hello, Subprocess!']
Subprocess 提供了三个函数以不同的方式创建子进程。 : Command '['ls', '-I']' returned non-zero exit status 1 2.3 subprocess.check_output() 和 subprocess.check_call 举个例子, import subprocess sbp=subprocess.Popen(["ping","-c","5","www.youzan.com"]) print "ping is not 怎么使用Python的subprocess来解决呢? 五 参考资料 [1] 官方文档 [2] Python中的subprocess与Pipe [3] python类库31[进程subprocess]
subprocess.call(),subprocess.getoutput()等上面列出的其他函数来使用subprocess模块的功能; subprocess.run()、subprocess.call ()、subprocess.check_call()和subprocess.check_output()都是通过对subprocess.Popen的封装来实现的高级函数,因此如果我们需要更复杂功能时,可以通过 obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE 捕获错误输出 proc = subprocess.Popen(['python3'],stdin=subprocess.PIPE,stdout=subprocess.PIPE, stderr=subprocess.PIPE 当subprocess.call()、subprocess.check_call()、subprocess.check_output()和subprocess.run()这些高级函数无法满足需求时,我们可以使用
的subprocess模块执行外部命令时,有时候会遇到CalledProcessError的异常,这个异常表示执行的命令返回一个非零的退出状态码。 接着使用subprocess.run执行命令生成PDF图形,并检查生成的PDF文件是否存在及具备读取权限。最后将生成的PDF文件移动到指定的输出路径。 subprocess模块也提供了一些其他函数和常量,用于设置和处理子进程的其他参数和属性,例如设置执行路径、设置环境变量、设置超时时间等。 使用subprocess模块可以方便地调用外部程序、执行系统命令、进行并行处理等。它在很多场景中都非常有用,例如执行外部命令、调用系统工具、进行系统管理等。 然而,由于涉及到操作系统的底层调用,使用subprocess模块时需要注意安全性、错误处理和兼容性,以确保程序的稳定性和可靠性。
背景 python执行操作系统的命令,如python执行shell命令 subprocess模块主要用于创建子进程,并连接它们的输入、输出和错误管道,获取它们的返回状态。 操作 引用 python自带subprocess包,直接import引入即可 import subprocess 常用方法 需要注意2.X版本和3.X版本 3.X版本 推荐使用run方法,3.5版本才新增该方法 其值可以是subprocess.PIPE、subprocess.DEVNULL、一个已经存在的文件描述符、已经打开的文件对象或者None。subprocess.PIPE表示为子进程创建新的管道。 >>> subprocess.run("exit 1", shell=True, check=True) Traceback (most recent call last): ... subprocess.CalledProcessError 1 root root 1, 3 Jan 23 16:23 /dev/null\n') >>> subprocess.run("python --version", stdout=subprocess.PIPE
(): 用法与subprocess.call()类似,区别是,当返回值不为0时,直接抛出异常 示例: >>> a = subprocess.check_call('df -hT',shell=True) (["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) obj.stdin.write obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE child1 = subprocess.Popen(["cat","/etc/passwd"], stdout=subprocess.PIPE) child2 = subprocess.Popen([ child = subprocess.Popen('sleep 60',shell=True,stdout=subprocess.PIPE) child.poll() #检查子进程状态 child.kill
subprocess.call(),subprocess.getoutput()等上面列出的其他函数来使用subprocess模块的功能;3.subprocess.run()、subprocess.call ()、subprocess.check_call()和subprocess.check_output()都是通过对subprocess.Popen的封装来实现的高级函数,因此如果我们需要更复杂功能时,可以通过 (["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)>>> obj.stdin.write >>> >>> p1 = subprocess.Popen(['df', '-Th'], stdout=subprocess.PIPE)>>> p2 = subprocess.Popen(['grep' 当subprocess.call()、subprocess.check_call()、subprocess.check_output()和subprocess.run()这些高级函数无法满足需求时,我们可以使用
本篇,将详细介绍Python创建附加进行的库:subprocess。 run(运行外部命令) subprocess库本身可以替换os.system(),os.spawnv()等函数。 import subprocess completed = subprocess.run('whoami',stdout=subprocess.PIPE) print(completed.returncode , stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) except subprocess.CalledProcessError 示例如下: import subprocess prc = subprocess.Popen('whoami', stdout=subprocess.PIPE) stdout_value = prc.communicate import subprocess prc = subprocess.Popen(["cmd", "/c", 'type', '-'], stdin=subprocess.PIPE) prc.communicate
,用 Python 3.7进行了测试: import subprocess import time def main(): proc = subprocess.Popen(['ping', '- proc = subprocess.Popen(['ping', '-c', '3', '127.0.0.1'], stdout=subprocess.PIPE exited with rc =', proc.returncode) except subprocess.TimeoutExpired: print('subprocess 下面是: def main(): proc = subprocess.Popen(['python', '-i'], stdin=subprocess.PIPE , stdout=subprocess.PIPE, stderr=subprocess.PIPE
小心调用 subprocess,避免因 shell=True 而命令行解析错误 Python 中的 subprocess 模块可以轻松实现执行外部命令和进程的功能。 但是在使用 subprocess 调用复杂命令时,有一个容易犯但影响比较大的错误 - 使用shell=True参数,导致命令行解析错误,子进程执行失败。 " subprocess.call(cmd, shell=True) 执行后,这个命令同样会解析失败,因为管道符号 | 被 shell 作为字符串传递,而不是真实的管道。 总结 综上,调用 subprocess 执行复杂命令时,如果不必要,最好避免使用 shell=True。直接传入命令列表,可以最大限度避免命令行解析错误的问题。 记录这个教训,在将来调用 subprocess 时多加注意,可以避免很多定制错误和调试时间,让代码更稳定。controllers 和 timeframe 数据结构。
这三个函数的使用方法相类似,我们以subprocess.call()来说明: import subprocess rc = subprocess.call(["ls","-l"]) 我们将程序名(ls) 和所带的参数(-l)一起放在一个表中传递给subprocess.call() 可以通过一个shell来解释一整个字符串: import subprocess out = subprocess.call( 将多个子进程的输入和输出连接在一起,构成管道(pipe): import subprocess child1 = subprocess.Popen(["ls","-l"], stdout=subprocess.PIPE 我们还可以利用communicate()方法来使用PIPE给子进程输入: import subprocess child = subprocess.Popen(["cat"], stdin=subprocess.PIPE 总结 subprocess.call, subprocess.check_call(), subprocess.check_output() subprocess.Popen(), subprocess.PIPE