subprocess 您所在的位置:网站首页 cmd简单命令 subprocess

subprocess

2023-06-15 09:42| 来源: 网络整理| 查看: 265

在一个新的进程中执行子程序。 在 POSIX 上,该类会使用类似于 os.execvpe() 的行为来执行子程序。 在 Windows 上,该类会使用 Windows CreateProcess() 函数。 Popen 的参数如下。

args 应当是一个程序参数的序列或者是一个单独的字符串或 path-like object。 默认情况下,如果 args 是序列则要运行的程序为 args 中的第一项。 如果 args 是字符串,则其解读依赖于具体平台,如下所述。 请查看 shell 和 executable 参数了解其与默认行为的其他差异。 除非另有说明,否则推荐以序列形式传入 args。

警告

For maximum reliability, use a fully qualified path for the executable. To search for an unqualified name on PATH, use shutil.which(). On all platforms, passing sys.executable is the recommended way to launch the current Python interpreter again, and use the -m command-line format to launch an installed module.

对 executable (或 args 的第一项) 路径的解析方式依赖于具体平台。 对于 POSIX,请参阅 os.execvpe(),并要注意当解析或搜索可执行文件路径时,cwd 会覆盖当前工作目录而 env 可以覆盖 PATH 环境变量。 对于 Windows,请参阅 lpApplicationName 的文档以及 lpCommandLine 形参 (传给 WinAPI CreateProcess),并要注意当解析或搜索可执行文件路径时如果传入 shell=False,则 cwd 不会覆盖当前工作目录而 env 无法覆盖 PATH 环境变量。 使用完整路径可避免所有这些变化情况。

向外部函数传入序列形式参数的一个例子如下:

Popen(["/usr/bin/git", "commit", "-m", "Fixes a bug."])

在 POSIX,如果 args 是一个字符串,此字符串被作为将被执行的程序的命名或路径解释。但是,只有在不传递任何参数给程序的情况下才能这么做。

备注

将 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 版更改: 在 POSIX 上如果 shell 为 False 并且序列包含路径类对象则 args 形参可以接受一个 path-like object。

在 3.8 版更改: 如果在Windows 上 shell 为 False 并且序列包含字节串和路径类对象则 args 形参可以接受一个 path-like object。

参数 shell (默认为 False)指定是否使用 shell 执行程序。如果 shell 为 True,更推荐将 args 作为字符串传递而非序列。

在 POSIX,当 shell=True, shell 默认为 /bin/sh。如果 args 是一个字符串,此字符串指定将通过 shell 执行的命令。这意味着字符串的格式必须和在命令提示符中所输入的完全相同。这包括,例如,引号和反斜杠转义包含空格的文件名。如果 args 是一个序列,第一项指定了命令,另外的项目将作为传递给 shell (而非命令) 的参数对待。也就是说, Popen 等同于:

Popen(['/bin/sh', '-c', args[0], args[1], ...])

在 Windows,使用 shell=True,环境变量 COMSPEC 指定了默认 shell。在 Windows 你唯一需要指定 shell=True 的情况是你想要执行内置在 shell 中的命令(例如 dir 或者 copy)。在运行一个批处理文件或者基于控制台的可执行文件时,不需要 shell=True。

备注

在使用 shell=True 之前, 请阅读 Security Considerations 段落。

bufsize 将在 open() 函数创建了 stdin/stdout/stderr 管道文件对象时作为对应的参数供应:

0 表示不使用缓冲区 (读取与写入是一个系统调用并且可以返回短内容)

1 means line buffered (only usable if text=True or 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=True, executable 替换 args 指定运行的程序。但是,原始的 args 仍然被传递给程序。大多数程序将被 args 指定的程序作为命令名对待,这可以与实际运行的程序不同。在 POSIX, args 名作为实际调用程序中可执行文件的显示名称,例如 ps。如果 shell=True,在 POSIX, executable 参数指定用于替换默认 shell /bin/sh 的 shell。

在 3.6 版更改: 在POSIX 上 executable 形参可以接受一个 path-like object。

在 3.8 版更改: 在Windows 上 executable 形参可以接受一个字节串和 path-like object。

在 3.11.3 版更改: Changed Windows shell search order for shell=True. The current directory and %PATH% are replaced with %COMSPEC% and %SystemRoot%\System32\cmd.exe. As a result, dropping a malicious program named cmd.exe into a current directory no longer works.

stdin, stdout 和 stderr 分别指定了被执行程序的标准输入、标准输出和标准错误文件句柄。 合法的值包括 PIPE、DEVNULL、现存的文件描述符(一个正整数)、现存的带有合法文件描述符的 file object 以及 None。 PIPE 表示应该新建一个连接子进程的管道。 DEVNULL 表示将使用特殊的文件 os.devnull。 当使用默认设置 None 时,将不会进行任何重定向;子进程的文件流将继承自父进程。 另外,stderr 可以为 STDOUT,这表示来自子进程的 stderr 数据应当被捕获到与 stdout 相同的文件句柄中。

如果 preexec_fn 被设为一个可调用对象,此对象将在子进程刚创建时被调用。(仅 POSIX)

警告

The preexec_fn parameter is NOT SAFE to use in the presence of threads in your application. The child process could deadlock before exec is called.

备注

If you need to modify the environment for the child use the env parameter rather than doing it in a preexec_fn. The start_new_session and process_group parameters should take the place of code using preexec_fn to call os.setsid() or os.setpgid() in the child.

在 3.8 版更改: preexec_fn 形参在子解释器中已不再受支持。 在子解释器中使用此形参将引发 RuntimeError。 这个新限制可能会影响部署在 mod_wsgi, uWSGI 和其他嵌入式环境中的应用。

如果 close_fds 为真,所有文件描述符除了 0, 1, 2 之外都会在子进程执行前关闭。而当 close_fds 为假时,文件描述符遵守它们继承的标志,如 文件描述符的继承 所述。

在 Windows,如果 close_fds 为真, 则子进程不会继承任何句柄,除非在 STARTUPINFO.IpAttributeList 的 handle_list 的键中显式传递,或者通过标准句柄重定向传递。

在 3.2 版更改: close_fds 的默认值已经从 False 修改为上述值。

在 3.7 版更改: 在 Windows,当重定向标准句柄时 close_fds 的默认值从 False 变为 True。现在重定向标准句柄时有可能设置 close_fds 为 True。(标准句柄指三个 stdio 的句柄)

pass_fds 是一个可选的在父子进程间保持打开的文件描述符序列。提供任何 pass_fds 将强制 close_fds 为 True。(仅 POSIX)

在 3.2 版更改: 加入了 pass_fds 形参。

如果 cwd 不为 None,此函数在执行子进程前会将当前工作目录改为 cwd。 cwd 可以是一个字符串、字节串或 路径类对象。 在 POSIX 上,如果可执行文件路径为相对路径则此函数会相对于 cwd 来查找 executable (或 args 的第一项)。

在 3.6 版更改: 在 POSIX 上 cwd 形参接受一个 path-like object。

在 3.7 版更改: 在 Windows 上 cwd 形参接受一个 path-like object。

在 3.8 版更改: 在 Windows 上 cwd 形参接受一个字节串对象。

 如果 restore_signals 为 true(默认值),则 Python 设置为 SIG_IGN 的所有信号将在 exec 之前的子进程中恢复为 SIG_DFL。目前,这包括 SIGPIPE ,SIGXFZ 和 SIGXFSZ 信号。 (仅 POSIX)

在 3.2 版更改: restore_signals 被加入。

If start_new_session is true the setsid() system call will be made in the child process prior to the execution of the subprocess.

可用性: POSIX

在 3.2 版更改: start_new_session 被添加。

If process_group is a non-negative integer, the setpgid(0, value) system call will be made in the child process prior to the execution of the subprocess.

可用性: POSIX

在 3.11 版更改: process_group was added.

如果 group 不为 None,则 setregid() 系统调用将于子进程执行之前在下级进程中进行。 如果所提供的值为一个字符串,将通过 grp.getgrnam() 来查找它,并将使用 gr_gid 中的值。 如果该值为一个整数,它将被原样传递。 (POSIX 专属)

可用性: POSIX

3.9 新版功能.

如果 extra_groups 不为 None,则 setgroups() 系统调用将于子进程之前在下级进程中进行。 在 extra_groups 中提供的字符串将通过 grp.getgrnam() 来查找,并将使用 gr_gid 中的值。 整数值将被原样传递。 (POSIX 专属)

可用性: POSIX

3.9 新版功能.

如果 user 不为 None,则 setreuid() 系统调用将于子进程执行之前在下级进程中进行。 如果所提供的值为一个字符串,将通过 pwd.getpwnam() 来查找它,并将使用 pw_uid 中的值。 如果该值为一个整数,它将被原样传递。 (POSIX 专属)

可用性: POSIX

3.9 新版功能.

如果 umask 不为负值,则 umask() 系统调用将在子进程执行之前在下级进程中进行。

可用性: POSIX

3.9 新版功能.

If env is not None, it must be a mapping that defines the environment variables for the new process; these are used instead of the default behavior of inheriting the current process' environment. This mapping can be str to str on any platform or bytes to bytes on POSIX platforms much like os.environ or os.environb.

备注

如果指定, env 必须提供所有被子进程需求的变量。在 Windows,为了运行一个 side-by-side assembly ,指定的 env 必须 包含一个有效的 SystemRoot。

If encoding or errors are specified, or text is true, the file objects stdin, stdout and stderr are opened in text mode with the specified encoding and errors, as described above in 常用参数. The universal_newlines argument is equivalent to text and is provided for backwards compatibility. By default, file objects are opened in binary mode.

3.6 新版功能: encoding 和 errors 被添加。

3.7 新版功能: text 作为 universal_newlines 的一个更具可读性的别名被添加。

如果给出, startupinfo 将是一个将被传递给底层的 CreateProcess 函数的 STARTUPINFO 对象。 creationflags,如果给出,可以是一个或多个以下标志之一:

CREATE_NEW_CONSOLE

CREATE_NEW_PROCESS_GROUP

ABOVE_NORMAL_PRIORITY_CLASS

BELOW_NORMAL_PRIORITY_CLASS

HIGH_PRIORITY_CLASS

IDLE_PRIORITY_CLASS

NORMAL_PRIORITY_CLASS

REALTIME_PRIORITY_CLASS

CREATE_NO_WINDOW

DETACHED_PROCESS

CREATE_DEFAULT_ERROR_MODE

CREATE_BREAKAWAY_FROM_JOB

当 PIPE 被用作 stdin, stdout 或 stderr 时 pipesize 可被用于改变管道的大小。 管道的大小仅会在受支持的平台上被改变(当撰写本文档时只有 Linux 支持)。 其他平台将忽略此形参。

3.10 新版功能: 增加了 pipesize 形参。

Popen 对象支持通过 with 语句作为上下文管理器,在退出时关闭文件描述符并等待进程:

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

引发一个 审计事件 subprocess.Popen,附带参数 executable, args, cwd, env。

在 3.2 版更改: 添加了上下文管理器支持。

在 3.6 版更改: 现在,如果 Popen 析构时子进程仍然在运行,则析构器会发送一个 ResourceWarning 警告。

在 3.8 版更改: 在某些情况下 Popen 可以使用 os.posix_spawn() 以获得更好的性能。在适用于 Linux 的 Windows 子系统和 QEMU 用户模拟器上,使用 os.posix_spawn() 的 Popen 构造器不再会因找不到程序等错误而引发异常,而是上下级进程失败并返回一个非零的 returncode。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有