On this page
子流程-子流程 Management
源代码: Lib/subprocess.py
subprocess模块允许您生成新进程,连接到它们的 Importing/输出/错误管道,并获取它们的返回代码。该模块旨在替换一些较旧的模块和Function:
os.system
os.spawn*
在以下各节中,将找到有关如何使用subprocess模块替换这些模块和Function的信息。
See also
PEP 324 – PEP 建议子流程模块
使用子流程模块
推荐的子流程调用方法是将run()函数用于它可以处理的所有用例。对于更高级的用例,可以直接使用基础Popen接口。
run()函数是在 Python 3.5 中添加的;如果您需要保持与旧版本的兼容性,请参见较旧的高级 API部分。
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 , * other_popen_kwargs * )- 运行* args *描述的命令。await 命令完成,然后返回CompletedProcess实例。
上面显示的参数只是最常见的参数,下面在常用参数中进行了描述(因此在缩写签名中使用仅关键字表示法)。完整函数签名与Popen构造函数的签名基本相同-该函数的大多数参数都传递给该接口。 (* timeout , input , check 和 capture_output *不是.)
如果* capture_output *为 true,则将捕获 stdout 和 stderr。使用时,内部Popen对象将自动由stdout=PIPE
和stderr=PIPE
创建。 * stdout 和 stderr 参数可能无法与 capture_output 同时提供。如果希望捕获并将两个流合并为一个,请使用stdout=PIPE
和stderr=STDOUT
而不是 capture_output *。
timeout *参数传递给Popen.communicate()。如果超时到期,子进程将被终止并 await。子进程终止后,将重新引发TimeoutExpired异常。
input 参数传递给Popen.communicate(),因此传递给子进程的 stdin。如果使用,则必须为字节序列,如果指定了 encoding 或 errors 或 text 为 true,则必须为字符串。使用时,内部Popen对象将pass
stdin=PIPE
自动创建,并且 stdin *参数也可能无法使用。
如果* check *为 true,并且进程以非零退出代码退出,则将引发CalledProcessError异常。该异常的属性保存参数,退出代码以及 stdout 和 stderr(如果已捕获)。
如果指定了* encoding 或 errors ,或者 text 为 true,则使用指定的 encoding 和 errors *或io.TextIOWrapper默认值以文本模式打开 stdin,stdout 和 stderr 的文件对象。 * universal_newlines 参数等效于 text *,并且是为了向后兼容而提供的。默认情况下,文件对象以二进制模式打开。
如果* env *不是None
,则它必须是为新进程定义环境变量的 Map。这些被用来代替继承当前进程环境的默认行为。它直接传递到Popen。
Examples:
>>> subprocess.run(["ls", "-l"]) # doesn't capture output
CompletedProcess(args=['ls', '-l'], returncode=0)
>>> subprocess.run("exit 1", shell=True, check=True)
Traceback (most recent call last):
...
subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1
>>> subprocess.run(["ls", "-l", "/dev/null"], capture_output=True)
CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0,
stdout=b'crw-rw-rw- 1 root root 1, 3 Jan 23 16:23 /dev/null\n', stderr=b'')
3.5 版中的新Function。
在 3.6 版中进行了更改:添加了* encoding 和 errors *参数
在 3.7 版中进行了更改:添加了* text 参数,作为 universal_newlines 的更易理解的别名。添加了 capture_output *参数。
类别
subprocess.
CompletedProcess
- run()的返回值,表示已完成的过程。
args
- 用于启动进程的参数。这可以是列表或字符串。
returncode
- 子进程的退出状态。通常,退出状态为 0 表示它已成功运行。
负值-N
表示该子级已被 signalN
终止(仅 POSIX)。
stdout
- 从子进程中捕获的标准输出。字节序列,如果使用编码,错误或 text = True 调用了run(),则为字符串。
None
(如果未捕获标准输出)。
- 从子进程中捕获的标准输出。字节序列,如果使用编码,错误或 text = True 调用了run(),则为字符串。
如果使用stderr=subprocess.STDOUT
运行该进程,则 stdout 和 stderr 将合并在此属性中,而stderr将是None
。
stderr
- 从子进程中捕获了 stderr。字节序列,如果使用编码,错误或 text = True 调用了run(),则为字符串。
None
(如果未捕获 stderr)。
- 从子进程中捕获了 stderr。字节序列,如果使用编码,错误或 text = True 调用了run(),则为字符串。
check_returncode
( )- 如果returncode不为零,请提出CalledProcessError。
3.5 版中的新Function。
subprocess.
DEVNULL
- 可以用作Popen的* stdin , stdout 或 stderr *参数的特殊值,表示将使用特殊文件os.devnull。
版本 3.3 中的新Function。
subprocess.
PIPE
- 可以用作Popen的* stdin , stdout 或 stderr *参数的特殊值,它指示应打开到标准流的管道。对Popen.communicate()最有用。
subprocess.
STDOUT
- 可以用作Popen的* stderr *参数的特殊值,它指示标准错误应与标准输出进入同一句柄。
exception
subprocess.
SubprocessError
- 该模块所有其他异常的 Base Class。
版本 3.3 中的新Function。
exception
subprocess.
TimeoutExpired
- 子类SubprocessError,在 await 子进程的超时到期时引发。
cmd
- 用于产生子进程的命令。
timeout
- 超时(以秒为单位)。
output
- 子进程的输出(如果被run()或check_output()捕获)。否则为
None
。
- 子进程的输出(如果被run()或check_output()捕获)。否则为
stdout
- 输出的别名,用于与stderr对称。
stderr
- 子进程的 Stderr 输出(如果被run()捕获)。否则,
None
。
- 子进程的 Stderr 输出(如果被run()捕获)。否则,
版本 3.3 中的新Function。
在版本 3.5 中更改:添加了* stdout 和 stderr *属性
exception
subprocess.
CalledProcessError
- 由check_call()或check_output()运行的进程返回非零退出状态时引发的SubprocessError子类。
returncode
- 子进程的退出状态。如果该过程由于 signal 而退出,则这将是负 signal 号。
cmd
- 用于产生子进程的命令。
output
- 子进程的输出(如果被run()或check_output()捕获)。否则为
None
。
- 子进程的输出(如果被run()或check_output()捕获)。否则为
stdout
- 输出的别名,用于与stderr对称。
stderr
- 子进程的 Stderr 输出(如果被run()捕获)。否则,
None
。
- 子进程的 Stderr 输出(如果被run()捕获)。否则,
在版本 3.5 中更改:添加了* stdout 和 stderr *属性
常用参数
为了支持各种用例,Popen构造函数(和便捷函数)接受大量可选参数。对于大多数典型用例,可以安全地将其中许多参数保留为其默认值。最常用的参数是:
Note
args 是所有调用所必需的,应为字符串或程序参数序列。通常最好提供一个参数序列,因为它允许模块处理任何必需的参数转义和引用(例如,允许在文件名中留空格)。如果传递单个字符串,则 shell *必须为True(请参见下文),否则该字符串必须简单地命名要执行的程序而无需指定任何参数。
stdin , stdout 和 stderr 分别指定执行程序的标准 Importing,标准输出和标准错误文件句柄。有效值为PIPE,DEVNULL,现有文件 Descriptors(正整数),现有文件对象和
None
。 PIPE指示应创建到子级的新管道。 DEVNULL表示将使用特殊文件os.devnull。使用None
的默认设置,将不会发生重定向。子级的文件句柄将从父级继承。另外, stderr 可以为STDOUT,表示子进程的 stderr 数据应与 stdout *捕获到同一文件句柄中。
如果指定了* encoding 或 errors 或 text (也称为 universal_newlines )为 true,则将使用 encoding 在文本模式下打开文件对象* stdin , stdout 和 stderr 。呼叫中指定的和错误或io.TextIOWrapper的默认值。
对于* stdin ,Importing 中的行尾字符'\n'
将转换为默认的行分隔符os.linesep。对于 stdout 和 stderr ,输出中的所有行尾都将转换为'\n'
。有关更多信息,请参见io.TextIOWrapper类的文档(当其构造函数的 newline *参数为None
时)。
如果不使用文本模式,则* stdin , stdout 和 stderr *将作为二进制流打开。不执行编码或行尾转换。
3.6 版的新Function:添加了* encoding 和 errors *参数。
3.7 版中的新增Function:添加了* text 参数作为 universal_newlines *的别名。
Note
Popen.communicate()方法不会更新文件对象Popen.stdin,Popen.stdout和Popen.stderr的换行属性。
如果* shell *是True
,则指定的命令将pass shell 执行。如果您主要将 Python 用于大多数系统 Shell 程序提供的增强控制流,并且仍然希望方便地访问其他 Shell 程序Function(例如 Shell 程序管道,文件名通配符,环境变量扩展以及将~
扩展到用户的家),则这很有用。目录。但是,请注意,Python 本身提供了许多类似 shell 的Function(特别是glob,fnmatch,os.walk(),os.path.expandvars(),os.path.expanduser()和shutil)的实现。
在版本 3.3 中更改:* universal_newlines *为True
时,该类使用编码locale.getpreferredencoding(False)而不是locale.getpreferredencoding()
。有关此更改的更多信息,请参见io.TextIOWrapper类。
Note
在使用shell=True
之前,请阅读Security Considerations部分。
Popen构造函数文档中对这些选项以及所有其他选项进行了详细说明。
Popen Constructor
该模块中的基础流程创建和 Management 由Popen类处理。它提供了很大的灵 Active,以便开发人员能够处理便捷Function未涵盖的不太常见的情况。
-
- 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 *)
- 在新进程中执行子程序。在 POSIX 上,该类使用类似os.execvp()的行为来执行子程序。在 Windows 上,该类使用 Windows
CreateProcess()
函数。 Popen的参数如下。
- class *
- args 应该是程序参数的序列,或者是单个字符串或path-like object。默认情况下,如果 args 是序列,则要执行的程序是 args 中的第一项。如果 args 是字符串,则解释取决于平台,并在下面进行描述。有关默认行为的其他区别,请参见 shell 和 executable 参数。除非另有说明,否则建议将 args *作为序列传递。
将一些参数作为序列传递给外部程序的示例是:
Popen(["/usr/bin/git", "commit", "-m", "Fixes a bug."])
在 POSIX 上,如果* args *是字符串,则将该字符串解释为要执行的程序的名称或路径。但是,只有在不将参数传递给程序的情况下才能执行此操作。
Note
如何将 shell 命令分成一系列参数可能并不明显,特别是在复杂的情况下。 shlex.split()可以说明如何为* args *确定正确的标记化:
>>> import shlex, subprocess
>>> command_line = input()
/bin/vikings -input eggs.txt -output "spam spam.txt" -cmd "echo '$MONEY'"
>>> args = shlex.split(command_line)
>>> print(args)
['/bin/vikings', '-input', 'eggs.txt', '-output', 'spam spam.txt', '-cmd', "echo '$MONEY'"]
>>> p = subprocess.Popen(args) # Success!
特别要注意的是,在 Shell 程序中由空格分隔的选项(例如* -input )和参数(例如 eggs.txt )位于单独的列表元素中,而在参数中使用引号或反斜杠转义的参数 Shell 程序(例如,包含空格的文件名或上面显示的 echo *命令)是单个列表元素。
在 Windows 上,如果* args *是一个序列,它将以在 Windows 上将参数序列转换为字符串中描述的方式转换为字符串。这是因为基础CreateProcess()
对字符串进行操作。
在版本 3.6 中更改:如果* shell 为False
,则 args *参数接受path-like object,并且在 POSIX 上包含包含类似路径的对象的序列。
在 3.8 版中进行了更改:如果* shell 为False
,则 args *参数将接受path-like object,并且在 Windows 上将包含字节和类似路径的对象的序列。
- shell 参数(默认为
False
)指定是否将 shell 用作要执行的程序。如果 shell 是True
,建议将 args *作为字符串而不是序列传递。
在带有shell=True
的 POSIX 上,shell 默认为/bin/sh
。如果* args 是字符串,则该字符串指定要pass Shell 执行的命令。这意味着字符串的格式必须与在 shell 提示符下键入时的格式完全相同。例如,这包括在文件名中使用引号或反斜杠转义。如果 args *是序列,则第一项指定命令字符串,任何其他项将被视为 shell 本身的其他参数。也就是说,Popen等效于:
Popen(['/bin/sh', '-c', args[0], args[1], ...])
在具有shell=True
的 Windows 上, COMSPEC
环境变量指定默认 Shell 程序。在 Windows 上唯一需要指定shell=True
的是 Shell 中内置了要执行的命令(例如 dir 或 copy )。您不需要shell=True
即可运行批处理文件或基于控制台的可执行文件。
Note
在使用shell=True
之前,请阅读Security Considerations部分。
创建 stdin/stdout/stderr 管道文件对象时,* bufsize *将作为open()函数的相应参数提供:
0
表示无缓冲(读和写是一个系统调用,并且可以返回短整数)1
表示行缓冲(仅在universal_newlines=True
,即在文本模式下可用)任何其他正值表示使用大约该大小的缓冲区
负 bufsize(默认值)表示将使用 io.DEFAULT_BUFFER_SIZE 的系统默认值。
在 3.3.1 版本变更:* BUFSIZE *现在默认为-1 默认情况下启用缓冲匹配的行为,大多数代码期望。在 Python 3.2.4 和 3.3.1 之前的版本中,它错误地默认为0
,这是未缓冲的并且允许短读取。这是无意的,并且与大多数代码所期望的不匹配 Python 2 的行为。
- executable 参数指定要执行的替换程序。很少需要。当
shell=False
时, executable 替换要由 args 指定的程序。但是,原始的 args 仍会传递给程序。大多数程序将 args 指定的程序视为命令名称,然后该名称可能与实际执行的程序不同。在 POSIX 上, args 名称成为 Util(例如 ps )中可执行文件的显示名称。如果shell=True
,则在 POSIX 上, executable *参数指定默认/bin/sh
的替换壳。
在 3.6 版中进行了更改:* executable *参数在 POSIX 上接受path-like object。
在 3.8 版中进行了更改:* executable *参数在 Windows 上接受字节和path-like object。
- stdin , stdout 和 stderr 分别指定执行程序的标准 Importing,标准输出和标准错误文件句柄。有效值为PIPE,DEVNULL,现有文件 Descriptors(正整数),现有file object和
None
。 PIPE指示应创建到子级的新管道。 DEVNULL表示将使用特殊文件os.devnull。使用None
的默认设置,将不会发生重定向。子级的文件句柄将从父级继承。此外, stderr *可以为STDOUT,指示应将来自应用程序的 stderr 数据捕获到与 stdout 相同的文件句柄中。
如果将* preexec_fn *设置为可调用对象,则将在子进程执行之前在子进程中调用该对象。 (仅 POSIX)
Warning
在应用程序中存在线程的情况下,* preexec_fn *参数不安全使用。在调用 exec 之前,子进程可能会死锁。如果必须使用它,请尽量不要使用它!最小化您要调用的库的数量。
Note
如果您需要为孩子修改环境,请使用* env 参数,而不要在 preexec_fn *中进行设置。 * start_new_session 参数可以代替 preexec_fn *以前在子对象中调用 os.setsid()的常用用法。
在 3.8 版中进行了更改:子解释器不再支持* preexec_fn *参数。在子解释器中使用参数会引发RuntimeError。新的限制可能会影响在 mod_wsgi,uWSGI 和其他嵌入式环境中部署的应用程序。
如果* close_fds 为 true,则在执行子进程之前,将关闭除0
,1
和2
以外的所有文件 Descriptors。否则,当 close_fds *为 false 时,文件 Descriptors 遵循文件 Descriptors 的继承中所述的可继承标志。
在 Windows 上,如果* close_fds *为 true,则子进程将不会继承任何句柄,除非在STARTUPINFO.lpAttributeList的handle_list
元素中显式传递或pass标准句柄重定向来传递。
在版本 3.2 中进行了更改:* close_fds *的默认值已从False更改为上述内容。
在版本 3.7 中进行了更改:在 Windows 上,重定向标准句柄时,* close_fds 的默认值已从False更改为True。现在,当重定向标准句柄时,可以将 close_fds *设置为True。
- pass_fds 是可选的文件 Descriptors 序列,用于保持父级和子级之间的打开状态。提供任何 pass_fds 会强制 close_fds *为True。 (仅 POSIX)
在版本 3.2 中更改:添加了* pass_fds *参数。
如果* cwd 不是None
,则函数在执行子级之前将工作目录更改为 cwd *。 * cwd 可以是字符串,字节或path-like对象。特别是,如果可执行路径是相对路径,则该函数将相对于 cwd 寻找 executable (或 args *中的第一项)。
在版本 3.6 中更改:* cwd *参数在 POSIX 上接受path-like object。
在版本 3.7 中更改:* cwd *参数在 Windows 上接受path-like object。
在版本 3.8 中更改:* cwd *参数在 Windows 上接受字节对象。
如果* restore_signals *为 true(默认设置),则在执行之前,子进程中将 Python 设置为 SIG_IGN 的所有 signal 都还原为 SIG_DFL。当前,这包括 SIGPIPE,SIGXFZ 和 SIGXFSZsignal。 (仅 POSIX)
在 3.2 版中进行了更改:添加了* restore_signals *。
如果* start_new_session *为 true,则将在子进程执行之前在子进程中进行 setsid()系统调用。 (仅 POSIX)
在版本 3.2 中更改:添加了* start_new_session *。
如果* env *不是None
,则它必须是为新进程定义环境变量的 Map;这些被用来代替继承当前进程环境的默认行为。
Note
如果指定,* env 必须提供程序执行所需的任何变量。在 Windows 上,要运行side-by-side assembly,必须 env *必须包含有效的 SystemRoot
。
如果指定了* encoding 或 errors 或 text 为 true,则文件对象 stdin , stdout 和 stderr 将以指定的编码和 errors *在文本模式下打开,如上文常用参数。 * universal_newlines 参数等效于 text *,并且是为了向后兼容而提供的。默认情况下,文件对象以二进制模式打开。
3.6 版的新Function:添加了* encoding 和 errors *。
3.7 版中的新Function:添加了* text 作为 universal_newlines *的可读性更高的别名。
如果指定,则* startupinfo *将是一个STARTUPINFO对象,该对象将传递给基础CreateProcess
函数。 * creationflags *(如果提供)可以是以下一个或多个标志:
Note
passwith语句支持将 Popen 对象用作上下文 Management 器:退出时,标准文件 Descriptors 将关闭,并 await 该过程。
with Popen(["ifconfig"], stdout=PIPE) as proc:
log.write(proc.stdout.read())
Popen 和此模块中使用它的其他函数使用参数executable
,args
,cwd
和env
引发auditing event subprocess.Popen
。 args
的值可以是单个字符串或字符串列表,具体取决于平台。
在版本 3.2 中进行了更改:添加了上下文 Management 器支持。
在版本 3.6 中进行了更改:如果子进程仍在运行,则 Popen 析构函数现在会发出ResourceWarning警告。
在版本 3.8 中更改:Popen 在某些情况下可以使用os.posix_spawn()以获得更好的性能。在适用于 Linux 的 Windows 子系统和 QEMU 用户仿真上,使用os.posix_spawn()的 Popen 构造函数不再针对诸如缺少程序之类的错误引发异常,但子进程失败,返回非零returncode。
Exceptions
在新程序开始执行之前,子进程中引发的异常将在父进程中重新引发。
引发的最常见异常是OSError。例如,在try执行不存在的文件时,就会发生这种情况。应用程序应为OSErrorexception 做好准备。
如果使用无效参数调用Popen,则会引发ValueError。
如果被调用的进程返回一个非零的返回码,则check_call()和check_output()将提高CalledProcessError。
如果超时在进程退出之前到期,则所有接受* timeout *参数的函数和方法(例如call()和Popen.communicate())都将引发TimeoutExpired。
此模块中定义的异常都继承自SubprocessError。
Note
版本 3.3 中的新增Function:添加了SubprocessErrorBase Class。
Security Considerations
与其他一些 popen 函数不同,此实现绝不会隐式调用系统 Shell 程序。这意味着所有字符,包括 Shell 元字符,都可以安全地传递给子进程。如果passshell=True
显式调用了 shell,则应用程序有责任确保所有空白和元字符都被正确引用以避免shell injection漏洞。
使用shell=True
时,可以使用shlex.quote()函数适当地转义将用于构造 Shell 命令的字符串中的空格和 Shell 元字符。
Popen Objects
Popen类的实例具有以下方法:
Popen.
poll
( )- 检查子进程是否已终止。设置并返回returncode属性。否则,返回
None
。
- 检查子进程是否已终止。设置并返回returncode属性。否则,返回
Popen.
wait
(* timeout = None *)- await 子进程终止。设置并返回returncode属性。
如果该过程在* timeout *秒后仍未终止,请引发TimeoutExpired异常。捕获此异常并重试 await 是安全的。
Note
当使用stdout=PIPE
或stderr=PIPE
时,这将导致死锁,并且子进程会向管道生成足够的输出,从而阻塞 awaitOS 管道缓冲区接受更多数据的 await。使用管道时请使用Popen.communicate()来避免这种情况。
Note
该Function是pass忙循环(非阻塞呼叫和短暂睡眠)实现的。使用asyncio模块进行异步 await:请参见asyncio.create_subprocess_exec。
在版本 3.3 中更改:添加了超时。
Popen.
communicate
(* input = None , timeout = None *)- 与进程交互:将数据发送到 stdin。从 stdout 和 stderr 读取数据,直到到达文件末尾。await 进程终止并设置returncode属性。可选的* input 参数应该是要发送到子进程的数据,或者
None
(如果没有数据应该发送到子进程)。如果以文本模式打开流,则 input *必须为字符串。否则,它必须是字节。
- 与进程交互:将数据发送到 stdin。从 stdout 和 stderr 读取数据,直到到达文件末尾。await 进程终止并设置returncode属性。可选的* input 参数应该是要发送到子进程的数据,或者
communicate()返回一个 Tuples(stdout_data, stderr_data)
。如果以文本模式打开流,则数据将为字符串;否则,数据将为字符串。否则为字节。
请注意,如果要将数据发送到进程的 stdin,则需要使用stdin=PIPE
创建 Popen 对象。同样,要在结果 Tuples 中获得None
以外的任何内容,您也需要提供stdout=PIPE
和/或stderr=PIPE
。
如果该进程在* timeout *秒后仍未终止,则将引发TimeoutExpired异常。捕获此异常并重试通信不会丢失任何输出。
如果超时到期,子进程不会被杀死,因此为了正确清理行为良好的应用程序,应该杀死子进程并完成通信:
proc = subprocess.Popen(...)
try:
outs, errs = proc.communicate(timeout=15)
except TimeoutExpired:
proc.kill()
outs, errs = proc.communicate()
Note
读取的数据缓存在内存中,因此,如果数据大小很大或没有限制,请不要使用此方法。
在版本 3.3 中更改:添加了超时。
Popen.
send_signal
(* signal *)- 发送 signalsignal给孩子。
Note
在 Windows 上,SIGTERM 是terminate()的别名。可以将 CTRL_C_EVENT 和 CTRL_BREAK_EVENT 发送到以* creationflags *参数(包括 CREATE_NEW_PROCESS_GROUP)启动的进程。
Popen.
terminate
( )- 阻止孩子在 POSIXos 上,该方法将 SIGTERM 发送给子级。在 Windows 上,将调用 Win32 API 函数
TerminateProcess()
来停止子级。
- 阻止孩子在 POSIXos 上,该方法将 SIGTERM 发送给子级。在 Windows 上,将调用 Win32 API 函数
Popen.
kill
( )- 杀死孩子。在 POSIXos 上,该Function将 SIGKILL 发送给子级。在 Windows 上,kill()是terminate()的别名。
以下属性也可用:
Popen.
args
- 传递给Popen的* args *参数-程序参数序列或单个字符串。
版本 3.3 中的新Function。
Popen.
stdin
Popen.
stdout
Popen.
stderr
Warning
使用communicate()而不是.stdin.write,.stdout.read或.stderr.read来避免死锁,因为其他 OS 管道缓冲区中的任何一个都填满并阻塞了子进程。
Popen.
pid
- 子进程的进程 ID。
请注意,如果将* shell *参数设置为True
,则这是生成的 shell 的进程 ID。
Popen.
returncode
- 子返回码,由poll()和wait()设置(并由communicate()间接设置)。
None
值表示该进程尚未终止。
- 子返回码,由poll()和wait()设置(并由communicate()间接设置)。
负值-N
表示该子级已被 signalN
终止(仅 POSIX)。
Windows Popen 帮助器
STARTUPINFO类和以下常量仅在 Windows 上可用。
-
- class *
subprocess.
STARTUPINFO
(**, dwFlags = 0 , hStdInput = None , hStdOutput = None , hStdError = None , wShowWindow = 0 , lpAttributeList = None *)
- Windows STARTUPINFO结构的部分支持用于Popen的创建。可以pass将以下属性作为仅关键字的参数传递来设置以下属性。
- class *
在版本 3.7 中更改:添加了仅关键字参数支持。
dwFlags
- 一个位域,确定在进程创建窗口时是否使用某些STARTUPINFO属性。
si = subprocess.STARTUPINFO()
si.dwFlags = subprocess.STARTF_USESTDHANDLES | subprocess.STARTF_USESHOWWINDOW
hStdInput
- 如果dwFlags指定STARTF_USESTDHANDLES,则此属性是流程的标准 Importing 句柄。如果未指定STARTF_USESTDHANDLES,则标准 Importing 的默认值为键盘缓冲区。
hStdOutput
- 如果dwFlags指定STARTF_USESTDHANDLES,则此属性是该过程的标准输出句柄。否则,将忽略此属性,标准输出的默认值是控制台窗口的缓冲区。
hStdError
- 如果dwFlags指定STARTF_USESTDHANDLES,则此属性是该过程的标准错误句柄。否则,将忽略此属性,并且标准错误的默认值是控制台窗口的缓冲区。
wShowWindow
- 如果dwFlags指定STARTF_USESHOWWINDOW,则此属性可以是ShowWindow函数的
nCmdShow
参数中可以指定的任何值,但SW_SHOWDEFAULT
除外。否则,将忽略此属性。
- 如果dwFlags指定STARTF_USESHOWWINDOW,则此属性可以是ShowWindow函数的
为此属性提供了SW_HIDE。在passshell=True
调用Popen时使用。
lpAttributeList
- 如
STARTUPINFOEX
所示,用于创建进程的其他属性字典,请参见UpdateProcThreadAttribute。
- 如
Supported attributes:
handle_list
- Sequence of handles that will be inherited\. *close_fds* must be true if non\-empty\.
当传递给Popen构造函数时,句柄必须暂时由os.set_handle_inheritable()继承,否则OSError将引发 Windows 错误ERROR_INVALID_PARAMETER
(87)。
Warning
在多线程进程中,当将此Function与并发调用继承其他句柄(例如os.system())的其他进程创建函数结合使用时,请小心避免泄漏标记为可继承的句柄。这也适用于标准句柄重定向,它临时创建可继承的句柄。
3.7 版中的新Function。
Windows Constants
subprocess模块公开以下常量。
subprocess.
STD_INPUT_HANDLE
- 标准 Importing 设备。最初,这是控制台 Importing 缓冲区
CONIN$
。
- 标准 Importing 设备。最初,这是控制台 Importing 缓冲区
subprocess.
STD_OUTPUT_HANDLE
- 标准输出设备。最初,这是活动的控制台屏幕缓冲区
CONOUT$
。
- 标准输出设备。最初,这是活动的控制台屏幕缓冲区
subprocess.
STD_ERROR_HANDLE
- 标准错误设备。最初,这是活动的控制台屏幕缓冲区
CONOUT$
。
- 标准错误设备。最初,这是活动的控制台屏幕缓冲区
subprocess.
SW_HIDE
- 隐藏窗口。另一个窗口将被激活。
subprocess.
STARTF_USESTDHANDLES
subprocess.
STARTF_USESHOWWINDOW
- 指定STARTUPINFO.wShowWindow属性包含其他信息。
subprocess.
CREATE_NEW_CONSOLE
- 新进程具有一个新的控制台,而不是继承其父级的控制台(默认)。
subprocess.
CREATE_NEW_PROCESS_GROUP
如果指定了CREATE_NEW_CONSOLE,则忽略此标志。
subprocess.
ABOVE_NORMAL_PRIORITY_CLASS
- Popen
creationflags
参数,用于指定新进程的优先级高于平均水平。
- Popen
3.7 版中的新Function。
subprocess.
BELOW_NORMAL_PRIORITY_CLASS
- Popen
creationflags
参数,用于指定新进程的优先级低于平均水平。
- Popen
3.7 版中的新Function。
subprocess.
HIGH_PRIORITY_CLASS
- Popen
creationflags
参数,用于指定新进程具有较高的优先级。
- Popen
3.7 版中的新Function。
subprocess.
IDLE_PRIORITY_CLASS
- Popen
creationflags
参数,用于指定新进程将具有空闲(最低)优先级。
- Popen
3.7 版中的新Function。
subprocess.
NORMAL_PRIORITY_CLASS
- Popen
creationflags
参数,用于指定新进程具有正常优先级。 (默认)
- Popen
3.7 版中的新Function。
subprocess.
REALTIME_PRIORITY_CLASS
- Popen
creationflags
参数,用于指定新进程具有实时优先级。您几乎永远不要使用 REALTIME_PRIORITY_CLASS,因为这会break Management 鼠标 Importing,键盘 Importing 和后台磁盘刷新的系统线程。此类适用于直接与硬件“对话”或执行break较少的简短任务的应用程序。
- Popen
3.7 版中的新Function。
subprocess.
CREATE_NO_WINDOW
- Popen
creationflags
参数,用于指定新进程将不会创建窗口。
- Popen
3.7 版中的新Function。
subprocess.
DETACHED_PROCESS
- Popen
creationflags
参数,用于指定新进程将不会继承其父级的控制台。此值不能与 CREATE_NEW_CONSOLE 一起使用。
- Popen
3.7 版中的新Function。
subprocess.
CREATE_DEFAULT_ERROR_MODE
- Popen
creationflags
参数,用于指定新进程不继承调用进程的错误模式。而是,新进程将使用默认错误模式。对于禁用了硬错误的多线程 Shell 应用程序,此Function特别有用。
- Popen
3.7 版中的新Function。
subprocess.
CREATE_BREAKAWAY_FROM_JOB
- Popen
creationflags
参数,用于指定新流程未与作业关联。
- Popen
3.7 版中的新Function。
旧的高级 API
在 Python 3.5 之前,这三个函数包含用于 subprocess 的高级 API。现在,您可以在许多情况下使用run(),但是许多现有代码都调用了这些函数。
subprocess.
call
(* args *, *, stdin = None , stdout = None , stderr = None , shell = False , cwd = None , timeout = None , * other_popen_kwargs *)- 运行* args *描述的命令。await 命令完成,然后返回returncode属性。
需要捕获 stdout 或 stderr 的代码应改用run():
run(...).returncode
要抑制 stdout 或 stderr,请提供值DEVNULL。
上面显示的参数仅仅是一些常见的参数。完整函数签名与Popen构造函数的签名相同-该函数将所有提供的参数(除* timeout *之外)直接传递到该接口。
Note
请勿将此Function使用stdout=PIPE
或stderr=PIPE
。如果子进程向管道生成足够的输出以填充 OS 管道缓冲区,则该子进程将阻塞,因为未从中读取管道。
在版本 3.3 中更改:添加了超时。
subprocess.
check_call
(* args *, *, stdin = None , stdout = None , stderr = None , shell = False , cwd = None , timeout = None , * other_popen_kwargs *)- 使用参数运行命令。await 命令完成。如果返回码为零,则返回,否则加CalledProcessError。 CalledProcessError对象将在returncode属性中具有返回码。
需要捕获 stdout 或 stderr 的代码应改用run():
run(..., check=True)
要抑制 stdout 或 stderr,请提供值DEVNULL。
上面显示的参数仅仅是一些常见的参数。完整函数签名与Popen构造函数的签名相同-该函数将所有提供的参数(除* timeout *之外)直接传递到该接口。
Note
请勿将此Function使用stdout=PIPE
或stderr=PIPE
。如果子进程向管道生成足够的输出以填充 OS 管道缓冲区,则该子进程将阻塞,因为未从中读取管道。
在版本 3.3 中更改:添加了超时。
subprocess.
check_output
((args , , stdin = None , stderr = None , shell = False , cwd = None , encoding = None , errors = None , universal_newlines =无,超时=无,文本=无, * other_popen_kwargs *)- 运行带有参数的命令并返回其输出。
如果返回码非零,则会引发CalledProcessError。 CalledProcessError对象将在returncode属性中具有返回码,在output属性中具有任何输出。
这等效于:
run(..., check=True, stdout=PIPE).stdout
上面显示的参数仅仅是一些常见的参数。全Function签名与run()的签名基本相同-大多数参数直接传递给该接口。但是,不支持显式传递input=None
来继承父级的标准 Importing 文件句柄。
默认情况下,此函数将以编码字节的形式返回数据。输出数据的实际编码可能取决于调用的命令,因此对文本的解码通常需要在应用程序级别进行处理。
如常用参数和run()中所述,可以pass将_text_,* encoding , errors 或 universal_newlines *设置为True
来覆盖此行为。
要还捕获结果中的标准错误,请使用stderr=subprocess.STDOUT
:
>>> subprocess.check_output(
... "ls non_existent_file; exit 0",
... stderr=subprocess.STDOUT,
... shell=True)
'ls: non_existent_file: No such file or directory\n'
3.1 版中的新Function。
在版本 3.3 中更改:添加了超时。
在版本 3.4 中更改:添加了对* input *关键字参数的支持。
在 3.6 版中进行了更改:添加了* encoding 和 errors *。有关详情,请参见run()。
3.7 版中的新Function:添加了* text 作为 universal_newlines *的可读性更高的别名。
使用子流程模块替换旧Function
在本节中,“ a 变为 b”表示 b 可以替代 a。
Note
如果找不到执行的程序,则本节中的所有“ a”Function都会(或多或少)无声地失败。 “ b”替换项将引发OSError。
此外,如果所请求的操作产生非零的返回码,则使用check_output()进行的替换将以CalledProcessError失败。输出仍然可用作引发的异常的output属性。
在以下示例中,我们假设相关Function已经从subprocess模块导入。
替换/ bin/sh shell 命令替换
output=$(mycmd myarg)
becomes:
output = check_output(["mycmd", "myarg"])
替换 Shell 管道
output=$(dmesg | grep hda)
becomes:
p1 = Popen(["dmesg"], stdout=PIPE)
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
p1.stdout.close() # Allow p1 to receive a SIGPIPE if p2 exits.
output = p2.communicate()[0]
如果 p2 在 p1 之前退出,则启动 p2 之后的p1.stdout.close()
调用很重要,这样 p1 才能接收 SIGPIPE。
另外,对于受信任的 Importing,仍然可以直接使用 Shell 自身的管道支持:
output=$(dmesg | grep hda)
becomes:
output=check_output("dmesg | grep hda", shell=True)
Replacing os.system()
sts = os.system("mycmd" + " myarg")
# becomes
sts = call("mycmd" + " myarg", shell=True)
Notes:
- 通常不需要pass Shell 调用程序。
一个更现实的示例如下所示:
try:
retcode = call("mycmd" + " myarg", shell=True)
if retcode < 0:
print("Child was terminated by signal", -retcode, file=sys.stderr)
else:
print("Child returned", retcode, file=sys.stderr)
except OSError as e:
print("Execution failed:", e, file=sys.stderr)
替换 os.spawn 系列
P_NOWAIT example:
pid = os.spawnlp(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg")
==>
pid = Popen(["/bin/mycmd", "myarg"]).pid
P_WAIT example:
retcode = os.spawnlp(os.P_WAIT, "/bin/mycmd", "mycmd", "myarg")
==>
retcode = call(["/bin/mycmd", "myarg"])
Vector example:
os.spawnvp(os.P_NOWAIT, path, args)
==>
Popen([path] + args[1:])
Environment example:
os.spawnlpe(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg", env)
==>
Popen(["/bin/mycmd", "myarg"], env={"PATH": "/usr/bin"})
替换 os.popen(),os.popen2(),os.popen3()
(child_stdin, child_stdout) = os.popen2(cmd, mode, bufsize)
==>
p = Popen(cmd, shell=True, bufsize=bufsize,
stdin=PIPE, stdout=PIPE, close_fds=True)
(child_stdin, child_stdout) = (p.stdin, p.stdout)
(child_stdin,
child_stdout,
child_stderr) = os.popen3(cmd, mode, bufsize)
==>
p = Popen(cmd, shell=True, bufsize=bufsize,
stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
(child_stdin,
child_stdout,
child_stderr) = (p.stdin, p.stdout, p.stderr)
(child_stdin, child_stdout_and_stderr) = os.popen4(cmd, mode, bufsize)
==>
p = Popen(cmd, shell=True, bufsize=bufsize,
stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
(child_stdin, child_stdout_and_stderr) = (p.stdin, p.stdout)
返回码处理翻译如下:
pipe = os.popen(cmd, 'w')
...
rc = pipe.close()
if rc is not None and rc >> 8:
print("There were some errors")
==>
process = Popen(cmd, stdin=PIPE)
...
process.stdin.close()
if process.wait() != 0:
print("There were some errors")
替换 popen2 模块中的Function
Note
如果 popen2 函数的 cmd 参数是字符串,则pass/ bin/sh 执行命令。如果是列表,则直接执行命令。
(child_stdout, child_stdin) = popen2.popen2("somestring", bufsize, mode)
==>
p = Popen("somestring", shell=True, bufsize=bufsize,
stdin=PIPE, stdout=PIPE, close_fds=True)
(child_stdout, child_stdin) = (p.stdout, p.stdin)
(child_stdout, child_stdin) = popen2.popen2(["mycmd", "myarg"], bufsize, mode)
==>
p = Popen(["mycmd", "myarg"], bufsize=bufsize,
stdin=PIPE, stdout=PIPE, close_fds=True)
(child_stdout, child_stdin) = (p.stdout, p.stdin)
popen2.Popen3
和popen2.Popen4
基本上像subprocess.Popen一样工作,除了:
如果执行失败,Popen会引发异常。
-
- capturestderr 参数替换为 stderr *参数。
必须指定
stdin=PIPE
和stdout=PIPE
。popen2 默认情况下关闭所有文件 Descriptors,但是您必须将Popen指定为
close_fds=True
,以确保在所有平台或 Python 以前的版本上都具有此行为。
旧版 Shell 调用Function
该模块还从 2.x commands
模块提供以下旧版Function。这些操作隐式调用系统 Shell,并且上述关于安全性和异常处理一致性的保证对于这些Function均无效。
subprocess.
getstatusoutput
(* cmd *)- 在 shell 中返回执行* cmd *的
(exitcode, output)
。
- 在 shell 中返回执行* cmd *的
在带有Popen.check_output()
的 shell 中执行字符串* cmd *并返回 2Tuples(exitcode, output)
。使用语言环境编码;有关更多详细信息,请参见常用参数上的 Comments。
从输出中删除尾随换行符。该命令的退出代码可以解释为子流程的返回代码。例:
>>> subprocess.getstatusoutput('ls /bin/ls')
(0, '/bin/ls')
>>> subprocess.getstatusoutput('cat /bin/junk')
(1, 'cat: /bin/junk: No such file or directory')
>>> subprocess.getstatusoutput('/bin/junk')
(127, 'sh: /bin/junk: not found')
>>> subprocess.getstatusoutput('/bin/kill $$')
(-15, '')
Availability:POSIX 和 Windows。
在版本 3.3.4 中更改:添加了 Windows 支持。
该函数现在返回(退出代码,输出),而不是像在 Python 3.3.3 和更早版本中那样返回(状态,输出)。 exitcode 与returncode的值相同。
subprocess.
getoutput
(* cmd *)- 在 Shell 中返回执行* cmd *的输出(stdout 和 stderr)。
类似于getstatusoutput(),除了退出代码被忽略,返回值是包含命令输出的字符串。例:
>>> subprocess.getoutput('ls /bin/ls')
'/bin/ls'
Availability:POSIX 和 Windows。
在版本 3.3.4 中更改:添加了 Windows 支持
Notes
在 Windows 上将参数序列转换为字符串
在 Windows 上,* args *序列被转换为可以使用以下规则(与 MS C 运行时所使用的规则相对应)进行解析的字符串:
参数由空格分隔,空格可以是空格或制表符。
用双引号引起来的字符串被解释为单个参数,而不管其中包含的空格如何。带引号的字符串可以嵌入参数中。
在双引号之前加反斜杠的解释为字面量双引号。
反斜杠将按字面意义进行解释,除非它们紧接在双引号之前。
如果反斜杠紧接在双引号之前,则每对反斜杠都将被解释为 Literals 反斜杠。如果反斜杠的数量为奇数,则最后一个反斜杠将按照规则 3 中的说明转义下一个双引号。
See also
提供解析和转义命令行Function的模块。