python / 3.7.2rc1 / all / library-subprocess.html

子流程-子流程 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=PIPEstderr=PIPE创建。 * stdout stderr 参数可能无法与 capture_output 同时提供。如果希望捕获并将两个流合并为一个,请使用stdout=PIPEstderr=STDOUT而不是 capture_output *。

  • timeout *参数传递给Popen.communicate()。如果超时到期,子进程将被终止并 await。子进程终止后,将重新引发TimeoutExpired异常。

  • input 参数传递给Popen.communicate(),因此传递给子进程的 stdin。如果使用,则必须为字节序列,如果指定了 encoding errors text 为 true,则必须为字符串。使用时,内部Popen对象将passstdin=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(如果未捕获标准输出)。

如果使用stderr=subprocess.STDOUT运行该进程,则 stdout 和 stderr 将合并在此属性中,而stderr将是None

  • stderr

    • 从子进程中捕获了 stderr。字节序列,如果使用编码,错误或 text = True 调用了run(),则为字符串。 None(如果未捕获 stderr)。
  • check_returncode ( )

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

  • cmd

    • 用于产生子进程的命令。
  • timeout

    • 超时(以秒为单位)。
  • output

  • stdout

    • 输出的别名,用于与stderr对称。
  • stderr

    • 子进程的 Stderr 输出(如果被run()捕获)。否则,None

版本 3.3 中的新Function。

在版本 3.5 中更改:添加了* stdout stderr *属性

  • exception subprocess. CalledProcessError

  • returncode

    • 子进程的退出状态。如果该过程由于 signal 而退出,则这将是负 signal 号。
  • cmd

    • 用于产生子进程的命令。
  • output

  • stdout

    • 输出的别名,用于与stderr对称。
  • stderr

    • 子进程的 Stderr 输出(如果被run()捕获)。否则,None

在版本 3.5 中更改:添加了* stdout stderr *属性

常用参数

为了支持各种用例,Popen构造函数(和便捷函数)接受大量可选参数。对于大多数典型用例,可以安全地将其中许多参数保留为其默认值。最常用的参数是:

Note

  • args 是所有调用所必需的,应为字符串或程序参数序列。通常最好提供一个参数序列,因为它允许模块处理任何必需的参数转义和引用(例如,允许在文件名中留空格)。如果传递单个字符串,则 shell *必须为True(请参见下文),否则该字符串必须简单地命名要执行的程序而无需指定任何参数。

  • stdin stdout stderr 分别指定执行程序的标准 Importing,标准输出和标准错误文件句柄。有效值为PIPEDEVNULL,现有文件 Descriptors(正整数),现有文件对象和NonePIPE指示应创建到子级的新管道。 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.stdinPopen.stdoutPopen.stderr的换行属性。

如果* shell *是True,则指定的命令将pass shell 执行。如果您主要将 Python 用于大多数系统 Shell 程序提供的增强控制流,并且仍然希望方便地访问其他 Shell 程序Function(例如 Shell 程序管道,文件名通配符,环境变量扩展以及将~扩展到用户的家),则这很有用。目录。但是,请注意,Python 本身提供了许多类似 shell 的Function(特别是globfnmatchos.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的参数如下。
  • 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 中内置了要执行的命令(例如 dircopy )。您不需要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,标准输出和标准错误文件句柄。有效值为PIPEDEVNULL,现有文件 Descriptors(正整数),现有file objectNonePIPE指示应创建到子级的新管道。 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,则在执行子进程之前,将关闭除012以外的所有文件 Descriptors。否则,当 close_fds *为 false 时,文件 Descriptors 遵循文件 Descriptors 的继承中所述的可继承标志。

在 Windows 上,如果* close_fds *为 true,则子进程将不会继承任何句柄,除非在STARTUPINFO.lpAttributeListhandle_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 *(如果提供)可以是以下一个或多个标志:

passwith语句支持将 Popen 对象用作上下文 Management 器:退出时,标准文件 Descriptors 将关闭,并 await 该过程。

with Popen(["ifconfig"], stdout=PIPE) as proc:
    log.write(proc.stdout.read())

Popen 和此模块中使用它的其他函数使用参数executableargscwdenv引发auditing event subprocess.Popenargs的值可以是单个字符串或字符串列表,具体取决于平台。

在版本 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
  • Popen. wait(* timeout = None *)

    • await 子进程终止。设置并返回returncode属性。

如果该过程在* timeout *秒后仍未终止,请引发TimeoutExpired异常。捕获此异常并重试 await 是安全的。

Note

当使用stdout=PIPEstderr=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 *必须为字符串。否则,它必须是字节。

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()来停止子级。
  • Popen. kill ( )

    • 杀死孩子。在 POSIXos 上,该Function将 SIGKILL 发送给子级。在 Windows 上,kill()terminate()的别名。

以下属性也可用:

  • Popen. args
    • 传递给Popen的* args *参数-程序参数序列或单个字符串。

版本 3.3 中的新Function。

  • 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

Warning

使用communicate()而不是.stdin.write.stdout.read.stderr.read来避免死锁,因为其他 OS 管道缓冲区中的任何一个都填满并阻塞了子进程。

  • Popen. pid
    • 子进程的进程 ID。

请注意,如果将* shell *参数设置为True,则这是生成的 shell 的进程 ID。

  • Popen. returncode

负值-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将以下属性作为仅关键字的参数传递来设置以下属性。

在版本 3.7 中更改:添加了仅关键字参数支持。

  • dwFlags
    • 一个位域,确定在进程创建窗口时是否使用某些STARTUPINFO属性。
si = subprocess.STARTUPINFO()
si.dwFlags = subprocess.STARTF_USESTDHANDLES | subprocess.STARTF_USESHOWWINDOW
  • hStdInput

  • hStdOutput

    • 如果dwFlags指定STARTF_USESTDHANDLES,则此属性是该过程的标准输出句柄。否则,将忽略此属性,标准输出的默认值是控制台窗口的缓冲区。
  • hStdError

    • 如果dwFlags指定STARTF_USESTDHANDLES,则此属性是该过程的标准错误句柄。否则,将忽略此属性,并且标准错误的默认值是控制台窗口的缓冲区。
  • wShowWindow

为此属性提供了SW_HIDE。在passshell=True调用Popen时使用。

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$
  • subprocess. STD_OUTPUT_HANDLE

    • 标准输出设备。最初,这是活动的控制台屏幕缓冲区CONOUT$
  • subprocess. STD_ERROR_HANDLE

    • 标准错误设备。最初,这是活动的控制台屏幕缓冲区CONOUT$
  • subprocess. SW_HIDE

    • 隐藏窗口。另一个窗口将被激活。
  • subprocess. STARTF_USESTDHANDLES

  • subprocess. STARTF_USESHOWWINDOW

  • subprocess. CREATE_NEW_CONSOLE

    • 新进程具有一个新的控制台,而不是继承其父级的控制台(默认)。
  • subprocess. CREATE_NEW_PROCESS_GROUP

    • Popen creationflags参数,用于指定将创建一个新的过程组。对于在子进程上使用os.kill(),此标志是必需的。

如果指定了CREATE_NEW_CONSOLE,则忽略此标志。

  • subprocess. ABOVE_NORMAL_PRIORITY_CLASS
    • Popen creationflags参数,用于指定新进程的优先级高于平均水平。

3.7 版中的新Function。

  • subprocess. BELOW_NORMAL_PRIORITY_CLASS
    • Popen creationflags参数,用于指定新进程的优先级低于平均水平。

3.7 版中的新Function。

  • subprocess. HIGH_PRIORITY_CLASS
    • Popen creationflags参数,用于指定新进程具有较高的优先级。

3.7 版中的新Function。

  • subprocess. IDLE_PRIORITY_CLASS
    • Popen creationflags参数,用于指定新进程将具有空闲(最低)优先级。

3.7 版中的新Function。

  • subprocess. NORMAL_PRIORITY_CLASS
    • Popen creationflags参数,用于指定新进程具有正常优先级。 (默认)

3.7 版中的新Function。

  • subprocess. REALTIME_PRIORITY_CLASS
    • Popen creationflags参数,用于指定新进程具有实时优先级。您几乎永远不要使用 REALTIME_PRIORITY_CLASS,因为这会break Management 鼠标 Importing,键盘 Importing 和后台磁盘刷新的系统线程。此类适用于直接与硬件“对话”或执行break较少的简短任务的应用程序。

3.7 版中的新Function。

  • subprocess. CREATE_NO_WINDOW
    • Popen creationflags参数,用于指定新进程将不会创建窗口。

3.7 版中的新Function。

  • subprocess. DETACHED_PROCESS
    • Popen creationflags参数,用于指定新进程将不会继承其父级的控制台。此值不能与 CREATE_NEW_CONSOLE 一起使用。

3.7 版中的新Function。

  • subprocess. CREATE_DEFAULT_ERROR_MODE
    • Popen creationflags参数,用于指定新进程不继承调用进程的错误模式。而是,新进程将使用默认错误模式。对于禁用了硬错误的多线程 Shell 应用程序,此Function特别有用。

3.7 版中的新Function。

  • subprocess. CREATE_BREAKAWAY_FROM_JOB
    • Popen creationflags参数,用于指定新流程未与作业关联。

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=PIPEstderr=PIPE。如果子进程向管道生成足够的输出以填充 OS 管道缓冲区,则该子进程将阻塞,因为未从中读取管道。

在版本 3.3 中更改:添加了超时

  • subprocess. check_call(* args *, * stdin = None stdout = None stderr = None shell = False cwd = None timeout = None * other_popen_kwargs *)

需要捕获 stdout 或 stderr 的代码应改用run()

run(..., check=True)

要抑制 stdout 或 stderr,请提供值DEVNULL

上面显示的参数仅仅是一些常见的参数。完整函数签名与Popen构造函数的签名相同-该函数将所有提供的参数(除* timeout *之外)直接传递到该接口。

Note

请勿将此Function使用stdout=PIPEstderr=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 *)
    • 运行带有参数的命令并返回其输出。

如果返回码非零,则会引发CalledProcessErrorCalledProcessError对象将在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.Popen3popen2.Popen4基本上像subprocess.Popen一样工作,除了:

  • 如果执行失败,Popen会引发异常。

    • capturestderr 参数替换为 stderr *参数。
  • 必须指定stdin=PIPEstdout=PIPE

  • popen2 默认情况下关闭所有文件 Descriptors,但是您必须将Popen指定为close_fds=True,以确保在所有平台或 Python 以前的版本上都具有此行为。

旧版 Shell 调用Function

该模块还从 2.x commands模块提供以下旧版Function。这些操作隐式调用系统 Shell,并且上述关于安全性和异常处理一致性的保证对于这些Function均无效。

  • subprocess. getstatusoutput(* cmd *)
    • 在 shell 中返回执行* cmd *的(exitcode, output)

在带有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

  • shlex

  • 提供解析和转义命令行Function的模块。