python3的subprocess的各个方法的区别(-)
subprocess(python3.7)
subprocess 主要是为了替换一下的模块函数,允许你执行一些命令,并获取返回的状态码和 输入,输出和错误信息。
os.system
os.spawn*
subprocess 有好多方法,本文主要在总结下之间的区别是什么,最后官方推荐使用哪个。
subprocess的主要方法:
subprocess.run(),subprocess.Popen(),subprocess.call #这些模块都是基于Popen的
Python 3.5 之前
subprocess.call //call 系列 都是等待命令执行完, Wait for command to complete
subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False, cwd=None, timeout=None)
只返回执行结果的code 等同于subprocess.run(args).returncode
Note Do not use stdout=PIPE or stderr=PIPE with this function. The child process will block if it generates enough output to a pipe to fill up the OS pipe buffer as the pipes are not being read from.
############例子###
ret=subprocess.call(['ls', '-l']) # ret 程序执行结果返回值,正确执行都是0
----------------------------捕获输出结果到一个文件里Redirecting STDOUT to a File---
with open('joe.txt', 'w') as f: # 执行后joe.txt 文件内容为 Wed May 15 17:07:59 CST 2019
subprocess.call(['date'], stdout=f)
-------捕获输出结果到字符串,Redirecting STDOUT to strings---
ret=subprocess.check_output() #ret 为output内容(命令输出的内容) 等同于run(..., check=True, stdout=PIPE).stdout
-------------------
subprocess.check_call() #和 subprocess.call 一样,只是返回值不是0就引起异常,raise CalledProcessError ,等同于 subprocess.run(…, check=True)
-----输入stdin ----------
with open('joe.txt', 'r') as fr
subprocess.call(['cat'], stdin=f)
-------
######################################################
subprocess.Popen() #最基本的subprocess模块
class subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=None, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=(), *, encoding=None, errors=None, text=None)
p = subprocess.Popen(['ls', '-l']) #返回的p是Popen 对象
p(Popen对象) 有一下方法
p.poll() 检查子进程(cmd) 是否结束 ,如果没有结束会返回None,结束就返回return returncode
p.returncode 程序之后后的返回码,一般正常结束会返回0,否则会返回其他值
p.wait() 等待子进程结束,然后返回returncode值
If the process does not terminate after timeout seconds, raise a TimeoutExpired exception. It is safe to catch this exception and retry the wait.
Note This will deadlock when using stdout=PIPE or stderr=PIPE and the child process generates enough output to a pipe such that it blocks waiting for the OS pipe buffer to accept more data. Use Popen.communicate() when using pipes to avoid that.
Note The function is implemented using a busy loop (non-blocking call and short sleeps). Use the asyncio module for an asynchronous wait: see asyncio.create_subprocess_exec.
p.communicate() 和子进程交互,返回一个元祖,returns a tuple (stdout_data, stderr_data)
p.terminate() 终止子进程,相当于发送SIGTERM 信号,相当于kill (后面不加参数)
p.kill() 终止子进程,相当于发送SIGKILL 信号,相当于kill -9
p.stdin,p.stdout,p.stderr 分别是输入,输出,错误输出,在python3中都是byte类型需要decode转化
p.returncode() 程序的返回状态 ,程序没有结束的话会返回None
p.pid 返回程序的 pid
p.send_signal(signal) 发送一个信号给子进程
subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=None, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=(), *, encoding=None, errors=None, text=None)
Popen 参数:
------
args, a sequence of program arguments or else a single string(参数是一个序列如,列表,元祖等。或者参数是一个字符串),默认情况下,如果args是序列,则要执行的程序是args中的第一项。如果args是一个字符串,需要设置shell=True,即开启一个shell 执行一个字符串的命令,或者序列的第一项
-----
bufsize 参数,stdin,stdout,stderr的缓存参数
executable 参数
@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ,shell=True时 executable=, 用于替换系统默认的shell(一般是bash),
p = subprocess.Popen('echo $0',shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE,executable='/bin/zsh') out,_=p.communicate() print(out.decode())
输出>>>/bin/zsh
@@@@@@@@@@@@@@@@@@@@@@@@@ shell=False时 executable=xxx,xxx会替换序列的第一项,一下'ls' 替换了'cat' 最终执行了 ls 'a.py','a.txt','b.txt'
p = subprocess.Popen(['cat','a.py','a.txt','b.txt'],stdout=subprocess.PIPE,stderr=subprocess.PIPE,executable='ls') out,_=p.communicate() print(out.decode())
输出>>>a.py a.txt b.txt
python3.5 以后官方推荐使用run
p=subprocess.run
(args, ***, stdin=None, input=None, stdout=None, stderr=None, capture_output=False, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None, text=None, env=None, universal_newlines=None)
run 也是需要等进程结束后才返回结果,所以没有结束p.stdout等就不会输出结果
run的参数,和Popen 一样
capture_output =true 相当于stdout=PIPE
and stderr=PIPE
timeout 设置子进程超时时间,超时引起 TimeoutExpired异常
The timeout argument is passed to Popen.communicate()
. If the timeout expires, the child process will be killed and waited for. The TimeoutExpired
exception will be re-raised after the child process has terminated
input=xxx 相当于 Popen.communicate(xxx)和自动创建 stdin=PIPE
The input argument is passed to Popen.communicate()
and thus to the subprocess’s stdin. If used it must be a byte sequence, or a string if encoding or errors is specified or text is true. When used, the internal Popen
object is automatically created with stdin=PIPE
, and the stdin argument may not be used as well.
check check=True 如果程序返回状态码不是0 就引起异常CalledProcessError
If check is true, and the process exits with a non-zero exit code, a CalledProcessError
exception will be raised. Attributes of that exception hold the arguments, the exit code, and stdout and stderr if they were captured.
p=subprocess.run(), 执行run后会返回 CompletedProcess
类型 实例 P
实例P 有如下方法
p.args
p.returncode
p.stdout
p.stderr
p.check_returncode