subprogress允许我们创建新进程,进程之间通过stdin,stdout,stderr管道进行通信,该模块自从python2.4版本引入

这个模块是为了替代 os.system os.spawn*这两个模块产生的。也就是说,可以代替shell编写命令行脚本。

run 方法

The recommended approach to invoking subprocesses is to use the run() function for all use cases it can handle. For more advanced use cases, the underlying Popen interface can be used directly.

推荐使用run方法处理大部分场景,如果有更高级的需求,可以使用底层的Popen接口。

run()方法是python3.5加入的。(怪不得网上的教程都没看到这个方法)

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)

不过这个模块貌似只适合linux下使用。因为不支持powershell的那些命令(cmd 还是支持的)。windows下只有exe的可执行命令行程序比较适合调用吧。还有一点是,命令执行结果返回0和1,这点就和linux的命令式一致的。

run方法包含了大部分最常用的参数,而且很多接口参数都是和Popen一致

class subprocess.CompletedProcess

subprocess.CompletedProcess 是run方法的返回值

包含以下参数:

The return value from run(), representing a process that has finished.
args
The arguments used to launch the process. This may be a list or a string.
returncode
Exit status of the child process. Typically, an exit status of 0 indicates that it ran successfully.
A negative value -N indicates that the child was terminated by signal N (POSIX only).
stdout
Captured stdout from the child process. A bytes sequence, or a string if run() was called with an encoding, errors, or text=True. None if stdout was not captured.
If you ran the process with stderr=subprocess.STDOUT, stdout and stderr will be combined in this attribute, and stderr will be None.
stderr
Captured stderr from the child process. A bytes sequence, or a string if run() was called with an encoding, errors, or text=True. None if stderr was not captured.
check_returncode()
If returncode is non-zero, raise a CalledProcessError.
# win10 1809 python3.7
import subprocess
res = subprocess.run(['ffmpeg','-h'])
# subprocess.CompletedProcess
print('args: ',res.args)
print('stdout: ',res.stdout)
print('stderr: ',res.stderr)
# 当returncode为非零值,抛出错误 CalledProcessError
res.check_returncode()
args: ['ffmpeg', '-h']
stdout: None
stderr: None
subprocess.DEVNULL 应该就是linux里的 /dev/null
subprocess.PIPE 可以提供给stdin,stdout or stderr 参数
exception subprocess.SubprocessError
exception subprocess.TimeoutExpired
。。。

最常用的参数

args 调用的命令,可以是字符串,或者一系列的参数比如列表。

stdin stdout,stderr 程序的标准输入。。。 有效的参数值是PIPE和DEVNULL

text ,开启文本模式,可以用encoding指定编码,stdin等都会用文本形式传递。如果不开启,他们会以二进制流形式传递

在python3.7 text参数更名为universal_newlines

shell ,如果shell设置为true,命令会通过真正的shell环境执行。

# win10 1809 python3.7

import subprocess

subprocess.run('dir', shell=True)

CompletedProcess(args='dir', returncode=0)

popen对象

底层的进程创建和管理使用Popen class,灵活性比较高。

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)

Popen.send_signal(signal)

Popen.terminate() 停止

Popen.kill() 杀死子进程

Popen.pid 子进程的进程号

Popen.returncode 此进程的退出码

Popen.poll() 检查子进程是否停止

Popen.wait(timeout=None) 等待子进程停止,如果子进程超时还不termiate,会TimeoutExpired 异常

Popen.communicate(input=None, timeout=None)与进程交互,发送数据到stdin,并读取stdout和stderr直到eof

会返回一个元组(stdout_data, stderr_data),

Popen.stdin

如果 stdin 参数为 PIPE,此属性是一个类似 open() 返回的可写的流对象。如果 encoding 或 errors 参数被指定或者 universal_newlines 参数为 True,则此流是一个文本流,否则是字节流。如果 stdin 参数非 PIPE, 此属性为 None。

Popen.stdout

如果 stdout 参数是 PIPE,此属性是一个类似 open() 返回的可读流。从流中读取子进程提供的输出。如果 encoding 或 errors 参数被指定或者 universal_newlines 参数为 True,此流为文本流,否则为字节流。如果 stdout 参数非 PIPE,此属性为 None。

Popen.stderr

如果 stderr 参数是 PIPE,此属性是一个类似 open() 返回的可读流。从流中读取子进程提供的输出。如果 encoding 或 errors 参数被指定或者 universal_newlines 参数为 True,此流为文本流,否则为字节流。如果 stderr 参数非 PIPE,此属性为 None。

原来python官方文档中文也更新了不少