subprocess模块允许你创建新进程,链接到他们的输入/输出/错误 管道上,去获取他们的返回码。这个模块主要是为了替换一些旧的模块和函数,比如os.system
和os.spawn*
使用subprocess模块
run函数
推荐的调用子进程的方式是使用run()
函数,它可以处理所有的情况,在一些更高级的用例中,可以直接使用底层的Popen
接口。
subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, shell=False, timeout=None, check=False)
args是你要运行的命令,然后等待命令运行结束,然后返回一个CompletedProcess
实例
上面显示的参数是最常使用的,在下面的Frequently Used Arguments
有详细介绍。它默认不会捕获stdout或者stderr,为了捕获这些信息,给stdout或者stderr参数传递PIPE
。
timeout参数会被传递给Popen.communicate()
,如果到了timeout,子进程会被kill掉,在子进程被杀死之后会重新引发TimeoutExpired
异常
输入参数会被传递给Popen.communicate()
,然后会被作为子进程的输入。如果要使用这个参数,传递的必须是一个二进制序列,或者当universal_newlines=True
的时候可以传递一个字符串。当使用这个参数的时候,内部的Popen对象会自动的加入stdin=PIPE
创建对象,同时stdin参数将不会被使用。
如果check参数为True,如果子进程以非0状态码退出的话,一个CalledProcessError
异常将会被引发。异常会保持参数,退出码,stdout以及stderr,如果能捕获的话。
例子:
|
|
基本上最简单的用法就是check=True
,然后stdout=PIPE
直接调用run函数就好了
CompletedProcess
从run函数的返回值,表示一个进程已经结束
- args: 用来启动进程的参数,会是一个列表或者字符串
- returncode: 子进程的退出码,如果是0表示运行成功,负数-N表示子进程被信号N终止了
- stdout: 从子进程中捕获stdout,二进制序列,如果run函数加上
universal_newlines=True
调用就是一个字符串,如果什么都没捕获的话就是一个None - stderr: 跟上面一样
check_returncode()
: 如果returncode不是0,则引发一个CalledProcessError
DEVNULL
可以在stdin, stdout或者stderr中作为Popen的参数,用来指示os.devnull
文件将会被使用
PIPE
可以在stdin, stdout或者stderr中作为Popen的参数,用来指示标准流的管道应该被打开。
STDOUT
用在Popen的stderr参数,用来指示标准错误应该和标准输出一同处理
CalledProcessError
- returncode: 子进程的退出码,如果是0表示运行成功,负数-N表示子进程被信号N终止了
- cmd: 用来启动进程的命令
- output: 如果被run或者
check_output
捕获就是子进程的输出,否则是None - stdout:
- stderr
Frequently Used Arguments
为了支持更广泛的使用,Popen构造器和一些有用的函数,接受大量的可选参数。对于大部分典型使用来说,这些参数中的大部分都可以使用其默认值。经常需要使用的参数是这些:
args
每一次调用都需要这个参数,应该是一个字符串或者是程序的参数序列。通常建议传递参数序列,因为这样可以允许模块更好的处理转义和参数引用,比如在文件名中允许空格。如果传递了单个的字符串,shell参数应该为True或者是程序调用的时候不需要额外参数stdin, stdout, stderr
分别指定了程序的标准输入,标准输出和标准错误的文件处理器。有效的值是PIPE
,DEVNULL
,一个存在的文件描述符,一个存在的文件对象和None。PIPE
指定了一个连接到子进程的管道应该被创建。DEVNULL
指定了这个特殊的文件os.devnull
会被使用。默认值None说明没有重定向发生。子进程的文件处理器会继承父进程的。另外,stderr
将会是STDOUT
,表明子进程的stderr数据会和stdout一块捕获。universal_newlines
如果为False,stdin, stdout, stderr将会以二进制流的方式打开,并且没有行结束符。如果为True,将会以文本模式打开,并且使用locale.getpreferredencoding(False)
返回的编码方式。对于stdin,\n
将会被转换成默认的行分隔符os.linesep
。对于stderr和stdout,所有的行结束都会被转换成\n
。shell
如果为True,指定的命令将会通过shell来执行,在你主要用Python来做控制,但是又想有shell的便利性的时候很有用,比如shell管道,文件名通配符,环境变量扩展,~
用户家目录的扩展。然而,Python自己也实现了很多shell特性的东西,比如glob
,fnmatch
,os.walk()
,os.path.expandvars()
,os.path.expanduser()
和shutil