小言_互联网的博客

subprocess- 子流程管理

446人阅读  评论(0)

subprocess该模块允许您生成新进程,连接到其输入/输出/错误管道,并获取其返回代码。该模块打算替换几个较旧的模块和功能:
os.system
os.spawn*

使用模块subprocess

推荐的调用子流程的方法是将该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)

运行args描述的命令。等待命令完成,然后返回CompletedProcess实例。

上面显示的参数仅仅是最常用的参数,下面在“ 常用参数”中进行	了描述(因此在缩写签名中使用了仅关键字表示法)。完整的函数签名与Popen构造函数的签名基本相同-该函数的大多数参数都传递给该接口。(timeout, input, check和capture_output不是。)

如果capture_output为true,则将捕获stdout和stderr。使用时,将Popen使用stdout=PIPE和自动创建内部对象 stderr=PIPE。的标准输出和stderr的参数可能不能在相同的时间被供给capture_output。如果您希望捕获并将这两个流合并为一个,请使用stdout=PIPE和,stderr=STDOUT 而不是capture_output。

在超时参数传递给Popen.communicate()。如果超时到期,子进程将被终止并等待。该 TimeoutExpired异常会被重新提出的子进程终止后。

该输入参数被传递给Popen.communicate()并因此给 子过程的标准输入。如果使用,则必须为字节序列,如果指定了编码或错误或文本为true ,则必须为字符串 。使用内部Popen对象时,它会使用自动创建 stdin=PIPE,并且stdin参数也不能使用。

如果check为true,并且进程以非零退出代码退出, CalledProcessError则会引发异常。该异常的属性包含参数,退出代码以及stdout和stderr(如果已捕获)。

如果指定了编码或错误,或者文本为true,则使用指定的编码和错误或io.TextIOWrapper默认设置,以文本模式打开stdin,stdout和stderr的文件对象。该universal_newlines参数等同于文本,并提供向后兼容性。默认情况下,文件对象以二进制模式打开。

如果env不是None,则它必须是为新进程定义环境变量的映射。这些被用来代替继承当前进程环境的默认行为。它直接传递给Popen。

例子:

>>> 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版中的新功能。

3.6版中的更改:添加了编码和错误参数

在3.7版中进行了更改:添加了text参数,作为Universal_newlines的更易理解的别名。添加了capture_output参数。

class subprocess.CompletedProcess

来自的返回值run(),表示已完成的过程。

args
用于启动进程的参数。这可以是列表或字符串。

returncode
子进程的退出状态。通常,退出状态为0表示它已成功运行。

负值-N表示该子级已被信号终止 N(仅POSIX)。

stdout
从子进程中捕获的标准输出。一个字节序列,或者一个字符串(如果 run()使用编码,错误或text = True调用)。 None如果未捕获stdout。

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

check_returncode()
如果returncode为非零,则引发CalledProcessError。

subprocess.DEVNULL

可以用作stdin,stdout或stderr参数的特殊值,Popen并指示os.devnull 将使用特殊文件。

subprocess.PIPE

可以用作stdin,stdout或stderr参数的特殊值,Popen指示应打开到标准流的管道。最有用的Popen.communicate()。

subprocess.STDOUT

可以用作stderr参数的特殊值,它Popen指示标准错误应与标准输出进入同一句柄。

exception subprocess.SubprocessError

该模块所有其他异常的基类。

exception subprocess.TimeoutExpired

SubprocessError的子类,在等待子进程超时时引发。

cmd
用于产生子进程的命令。

timeout
超时(以秒为单位)。

output
子进程的输出(如果被run()或 捕获)check_output()。否则,None。

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

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

版本3.3中的新功能。
在版本3.5中进行了更改:添加了stdout和stderr属性

exception subprocess.CalledProcessError

SubprocessError的子类,当进程运行check_call()或返回非零退出状态时引发check_output() 。

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

cmd
用于产生子进程的命令。

output
子进程的输出(如果被run()或 捕获)check_output()。否则,None。

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

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

常用参数

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

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

stdin,stdout和stderr分别指定执行程序的标准输入,标准输出和标准错误文件句柄。有效值为PIPE,DEVNULL现有文件描述符(正整数),现有文件对象和None。 PIPE指示应该创建到子级的新管道。 DEVNULL表示os.devnull将使用特殊文件。使用默认设置时None,将不会发生重定向。子级的文件句柄将从父级继承。另外,stderr可以是 STDOUT,它指示子进程的stderr数据应捕获到与stdout相同的文件句柄中。

如果指定了编码或错误,或者文本(也称为 Universal_newlines)为true,则将使用调用中指定的编码和错误或的默认值以文本模式打开文件对象stdin,stdout和stderr。io.TextIOWrapper

对于stdin,输入中的行尾字符’\n’将转换为默认的行分隔符os.linesep。对于stdout和stderr,输出中的所有行尾都将转换为’\n’。有关更多信息,请参见io.TextIOWrapper当类的构造函数的newline参数为时该类的文档None。

如果不使用文本模式,则stdin,stdout和stderr将作为二进制流打开。不执行编码或行尾转换。

3.6版的新功能:添加了编码和错误参数。

版本3.7中的新增功能:添加了text参数作为Universal_newlines的别名。

注意 文件对象的newlines属性Popen.stdin, Popen.stdout并且Popen.stderr不会通过该Popen.communicate()方法进行更新。

如果shell是True,则将通过Shell执行指定的命令。如果您主要将Python用于大多数系统外壳程序提供的增强控制流,并且仍然希望方便地访问其他外壳程序功能(例如外壳程序管道,文件名通配符,环境变量扩展以及扩展~到用户的主目录),则这很有用。。但是请注意,Python本身提供了很多贝壳般的功能实现(特别是glob, fnmatch,os.walk(),os.path.expandvars(), os.path.expanduser(),和shutil)。

改变在3.3版本:当universal_newlines是True,类使用的编码 locale.getpreferredencoding(False) 来代替locale.getpreferredencoding()。有关io.TextIOWrapper此更改的更多信息,请参见 课程。

POPEN构造

该模块中的基础流程创建和管理由Popen类处理。它提供了很大的灵活性,以便开发人员能够处理便捷功能未涵盖的不太常见的情况。

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应该是程序参数的序列,或者是单个字符串。默认情况下,如果args是序列,则要执行的程序是args中的第一项。如果args是字符串,则解释取决于平台,并在下面进行描述。有关 默认行为的其他区别,请参见shell和可执行参数。除非另有说明,否则建议将args作为序列传递。

在POSIX上,如果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!

在Windows上,如果args是一个序列,它将以Windows 上将参数序列转换为字符串中所述的方式转换为字符串。这是因为底层CreateProcess()对字符串进行操作。

所述壳参数(默认为False)指定是否使用壳作为要执行的程序。如果shell是True,建议将args作为字符串而不是序列传递。

在POSIX with上shell=True,shell默认为/bin/sh。如果 args是字符串,则该字符串指定要通过外壳执行的命令。这意味着字符串的格式必须与在shell提示符下键入时的格式完全相同。例如,这包括在文件名中使用引号或反斜杠转义。如果args是序列,则第一项指定命令字符串,任何其他项都将被视为shell本身的其他参数。也就是说,Popen是否等效于:

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

在Windows上shell=True,带有COMSPEC环境变量指定默认外壳程序。shell=True在Windows上唯一需要指定的 是将要执行的命令内置到shell中(例如dir或copy)。您不需要 shell=True运行批处理文件或基于控制台的可执行文件。

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

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的行为。

该可执行文件参数指定的替代程序来执行。很少需要。何时shell=False,可执行文件替换由args指定执行的程序。但是,原始参数仍会传递给程序。大多数程序将args指定的程序当作命令名,然后可以与实际执行的程序不同。在POSIX上,args名称成为实用程序(例如ps)中可执行文件的显示名称 。如果shell=True在POSIX上,可执行参数为默认值指定替换壳/bin/sh。

stdin,stdout和stderr分别指定执行程序的标准输入,标准输出和标准错误文件句柄。有效值为PIPE,DEVNULL现有文件描述符(正整数),现有文件对象和None。 PIPE 指示应该创建到子级的新管道。 DEVNULL 表示os.devnull将使用特殊文件。使用默认设置时None,将不会发生重定向。子级的文件句柄将从父级继承。另外,stderr可以为 STDOUT,指示应将来自应用程序的stderr数据捕获到与stdout相同的文件句柄中。

如果将preexec_fn设置为可调用对象,则将在执行子级之前在子进程中调用此对象。(仅POSIX)

警告 如果您的应用程序中存在线程,则preexec_fn参数不安全使用。在调用exec之前,子进程可能会死锁。如果您必须使用它,请保持琐碎!最小化您要调用的库的数量。

注意 如果需要为子进程修改环境,请使用env 参数,而不要在preexec_fn中使用它。该start_new_session参数可以采用以前普遍使用的地点preexec_fn调用os.setsid()的孩子。

如果close_fds是真实的,所有的文件描述符除外0,1并 2执行子进程之前,将被关闭。否则,当close_fds是假的,如在文件描述符服从他们的可继承标志文件描述符的传承。

在Windows上,如果close_fds为true,则子进程将不会继承任何句柄,除非在的handle_list元素中 显式传递STARTUPINFO.lpAttributeList或通过标准的句柄重定向。

在版本3.2中更改:close_fds的默认值已从更改False为上述内容。

在版本3.7中更改:在Windows 上,重定向标准句柄时,close_fds的默认值已从更改False为 True。现在可以在重定向标准句柄时将close_fds设置为True。

pass_fds是可选的文件描述符序列,用于保持父级和子级之间的打开状态。提供任何pass_fds都会强制 close_fds为True。(仅POSIX)

:在3.2版本中的新的pass_fds加入参数。

如果cwd不是None,则该函数在执行子级之前将工作目录更改为 cwd。 CWD可以是一个str和 路径状对象。特别是, 如果可执行路径是相对路径,则该函数将查找相对于cwd的可执行文件(或args中的第一项)。

在版本3.6中更改:cwd参数接受类似路径的对象。

如果restore_signals为true(默认设置),则在执行之前,子进程中将Python设置为SIG_IGN的所有信号都还原为SIG_DFL。当前,这包括SIGPIPE,SIGXFZ和SIGXFSZ信号。(仅POSIX)

在版本3.2中更改:添加了restore_signals。

如果start_new_session是真setsid()系统调用将在之前的执行的子进程进行子。(仅POSIX)

在版本3.2中进行了更改:添加了start_new_session。

如果env不是None,则它必须是为新进程定义环境变量的映射。这些被用来代替继承当前进程环境的默认行为。

注意 如果指定,env必须提供程序执行所需的任何变量。在Windows上,为了运行并行程序集,指定的env 必须包含有效的SystemRoot。
如果指定了编码或错误,或者文本为true,则文件对象 stdin,stdout和stderr将以指定的编码和错误以文本模式打开,如上面“ 常用参数”中所述。该universal_newlines参数等同于文本,并提供向后兼容性。默认情况下,文件对象以二进制模式打开。

3.6版中的新功能:添加了编码和错误。

3.7版中的新功能:文本被添加为Universal_newlines的可读性更高的别名。

如果给定,startupinfo将是一个STARTUPINFO对象,该对象将传递给基础CreateProcess函数。 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

通过以下with语句,可以将Popen对象用作上下文管理器:在退出时,将关闭标准文件描述符,并等待该过程。

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

Exceptions

在新程序开始执行之前,子进程中引发的异常将在父进程中重新引发。

提出的最常见的例外是OSError。例如,在尝试执行不存在的文件时,就会发生这种情况。应用程序应为OSError例外做好准备 。

ValueError如果Popen使用无效参数调用A,则会引发A。

check_call()如果被调用的进程返回一个非零的返回码,check_output()它将提高 CalledProcessError。

接受超时参数的所有函数和方法,例如 call()和,如果超时在进程退出之前到期,Popen.communicate()则会增加TimeoutExpired。

此模块中定义的异常均继承自。SubprocessError

:在3.3版本中的新的加入的基类。SubprocessError

安全注意事项

与某些其他popen函数不同,此实现绝不会隐式调用系统外壳程序。这意味着所有字符(包括外壳元字符)都可以安全地传递给子进程。如果通过显式调用了外壳shell=True程序,则应用程序有责任确保适当地引用所有空格和元字符以避免 外壳程序注入 漏洞。

使用时shell=True,该shlex.quote()函数可用于适当地转义将用于构造Shell命令的字符串中的空格和Shell元字符。

POPEN对象

Popen该类的实例具有以下方法:

Popen.poll()

检查子进程是否已终止。设置并返回 returncode属性。否则,返回None。

Popen.wait(timeout = None )

等待子进程终止。设置并返回 returncode属性。

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

注意 使用stdout=PIPE或时,这将stderr=PIPE 导致死锁,并且子进程会向管道生成足够的输出,从而阻塞等待OS管道缓冲区接受更多数据的等待。使用Popen.communicate()管道时可避免这种情况。

注意 该功能是使用忙循环(非阻塞呼叫和短暂睡眠)实现的。使用asyncio模块进行异步等待:请参阅。asyncio.create_subprocess_exec

Popen.communicate(input = None,timeout = None )

与进程交互:将数据发送到stdin。从stdout和stderr读取数据,直到到达文件末尾。等待进程终止。可选的 输入参数应该是要发送到子进程的None数据,如果没有数据要发送到子进程 ,则为。如果以文本模式打开流,则输入必须为字符串。否则,它必须是字节。

communicate()返回一个元组。如果以文本模式打开流,则数据将为字符串;否则,数据为字符串。否则为字节。(stdout_data, stderr_data)

请注意,如果要将数据发送到进程的stdin,则需要使用创建Popen对象stdin=PIPE。同样,要获得None结果元组以外的任何内容 ,您也需要给出stdout=PIPE和/或 stderr=PIPE。

如果该过程在超时秒后仍未终止, TimeoutExpired则会引发异常。捕获此异常并重试通信不会丢失任何输出。

如果超时到期,子进程不会被杀死,因此为了正确清理行为良好的应用程序,应该杀死子进程并完成通信:
proc = subprocess.Popen(...)
try:
    outs, errs = proc.communicate(timeout=15)
except TimeoutExpired:
    proc.kill()
    outs, errs = proc.communicate()

注意 读取的数据缓存在内存中,因此,如果数据大小很大或没有限制,请不要使用此方法。

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

Popen.send_signal(signal)

将信号发送给孩子。
注意 在Windows上,SIGTERM是的别名terminate()。可以将CTRL_C_EVENT和CTRL_BREAK_EVENT发送到以creationflags 参数(包括CREATE_NEW_PROCESS_GROUP)启动的进程。

Popen.terminate()

阻止孩子 在Posix OS上,该方法将SIGTERM发送给子级。在Windows上,将调用Win32 API函数TerminateProcess()来停止子级。

Popen.kill()

杀死子进程。在Posix OS上,该功能将SIGKILL发送给子级。在Windows上kill()是的别名terminate()。

以下属性也是可用的:
Popen.args

该ARGS因为它传递给参数Popen的程序参数的序列或者一个字符串- 。

版本3.3中的新功能。

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。

警告 使用communicate()而不是.stdin.write, .stdout.read或.stderr.read避免由于其他任何OS管道缓冲区填充和阻塞子进程而导致死锁。

Popen.pid

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

Popen.returncode
子返回码,由poll()和设置(并由wait()间接设置communicate())。一个None值表示进程尚未结束。
负值-N表示该子级已被信号终止 N(仅POSIX)。

Windows Popen帮助器

该STARTUPINFO级和以下常量仅适用于Windows。

class subprocess.STARTUPINFO(*, dwFlags=0, hStdInput=None, hStdOutput=None, hStdError=None, wShowWindow=0, lpAttributeList=None)

Windows STARTUPINFO 结构的部分支持 用于Popen创建。可以通过将以下属性作为仅关键字的参数传递来设置以下属性。

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

dwFlags
一个位域,确定STARTUPINFO 在进程创建窗口时是否使用某些属性。

si = subprocess.STARTUPINFO()
si.dwFlags = subprocess.STARTF_USESTDHANDLES | subprocess.STARTF_USESHOWWINDOW

hStdInput
如果dwFlags指定STARTF_USESTDHANDLES,则此属性是流程的标准输入句柄。如果 STARTF_USESTDHANDLES未指定,则标准输入的默认值为键盘缓冲区。

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

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

wShowWindow
如果dwFlags指定STARTF_USESHOWWINDOW,则此属性可以是ShowWindow 函数的nCmdShow 参数中 可以指定的任何值,但除外。否则,将忽略此属性。SW_SHOWDEFAULT

SW_HIDE为该属性提供。Popen与一起使用时 使用shell=True。

lpAttributeList

有关过程创建的其他属性的字典 STARTUPINFOEX,请参见 UpdateProcThreadAttribute。

支持的属性:
	handle_list
		将被继承的句柄序列。如果非空,则close_fds必须为true。
		os.set_handle_inheritable()传递给Popen 构造函数时,必须暂时使这些句柄可继承,否则OSError将因Windows错误ERROR_INVALID_PARAMETER(87)引发 该句柄 。
		警告 在多线程流程中,将此功能与并发调用其他继承所有句柄的流程创建函数(例如)结合使用时,请小心避免泄漏标记为可继承的句柄os.system()。这也适用于标准句柄重定向,它临时创建可继承的句柄。
		
	3.7版中的新功能。

Windows常量

该模块公开以下常量。subprocess

subprocess.STD_INPUT_HANDLE
标准输入设备。最初,这是控制台输入缓冲区 CONIN$。

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

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

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

subprocess.STARTF_USESTDHANDLES
指定STARTUPINFO.hStdInput, STARTUPINFO.hStdOutput和STARTUPINFO.hStdError属性包含的附加信息。

subprocess.STARTF_USESHOWWINDOW
指定该STARTUPINFO.wShowWindow属性包含其他信息。

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

subprocess.CREATE_NEW_PROCESS_GROUP
一个参数,用于指定将创建一个新的流程组。 在子流程上使用此标志是必需的。Popen creationflagsos.kill()

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

subprocess.ABOVE_NORMAL_PRIORITY_CLASS
一个参数指定一个新的进程将有一个高于平均水平的优先级。Popen creationflags

3.7版中的新功能。

subprocess.BELOW_NORMAL_PRIORITY_CLASS
一个参数指定一个新的进程将有一个低于平均水平的优先级。Popen creationflags

3.7版中的新功能。

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

3.7版中的新功能。

subprocess.IDLE_PRIORITY_CLASS
一个参数,用于指定新进程将具有空闲(最低)优先级。Popen creationflags
3.7版中的新功能。

subprocess.NORMAL_PRIORITY_CLASS
一个参数指定一个新的进程将有一个正常的优先级。(默认)Popen creationflags
3.7版中的新功能。

subprocess.REALTIME_PRIORITY_CLASS
一个参数,用于指定新进程将具有实时优先级。您几乎永远不要使用REALTIME_PRIORITY_CLASS,因为这会中断管理鼠标输入,键盘输入和后台磁盘刷新的系统线程。此类适合于直接与硬件“对话”或执行短暂任务(应具有有限中断)的应用程序。Popen creationflags
3.7版中的新功能。

subprocess.CREATE_NO_WINDOW
一个参数指定一个新的进程不会创建一个窗口。Popen creationflags
3.7版中的新功能。

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

subprocess.CREATE_DEFAULT_ERROR_MODE
一个参数,用于指定新进程不继承调用进程的错误模式。而是,新进程将使用默认错误模式。对于禁用了硬错误的多线程外壳应用程序,此功能特别有用。Popen creationflags
3.7版中的新功能。

subprocess.CREATE_BREAKAWAY_FROM_JOB
一个参数,用于指定新流程不与作业关联。Popen creationflags
3.7版中的新功能。

较旧的高级

在Python 3.5之前,这三个函数包含用于子流程的高级API 。您现在可以run()在许多情况下使用,但是许多现有代码都调用了这些函数。

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

运行args描述的命令。等待命令完成,然后返回returncode属性。

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

运行(...)。返回码

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

上面显示的参数仅仅是一些常见的参数。完整的函数签名与Popen构造函数的签名相同-该函数将超时以外的所有提供的参数直接传递给该接口。

注意 请勿使用stdout=PIPE或stderr=PIPE与此功能一起使用。如果子进程向管道生成足够的输出以填充OS管道缓冲区,则该子进程将阻塞,因为未从中读取管道。

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

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

使用参数运行命令。等待命令完成。如果返回码为零,则返回,否则返回CalledProcessError。该 CalledProcessError对象将在returncode属性中包含返回码 。

需要捕获stdout或stderr的代码应run()改为:
	run(…, check=True)

上面显示的参数仅仅是一些常见的参数。完整的函数签名与Popen构造函数的签名相同-该函数将超时以外的所有提供的参数直接传递给该接口。

注意 请勿使用stdout=PIPE或stderr=PIPE与此功能一起使用。如果子进程向管道生成足够的输出以填充OS管道缓冲区,则该子进程将阻塞,因为未从中读取管道。

subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, cwd=None, encoding=None, errors=None, universal_newlines=None, timeout=None, text=None)

运行带有参数的命令并返回其输出。
如果返回码非零,则会引发一个CalledProcessError。该 CalledProcessError对象将在returncode属性中具有返回码,在 属性中具有任何输出 output。
这等效于:
run(..., check=True, stdout=PIPE).stdout

上面显示的参数仅仅是一些常见的参数。全功能签名与run()_ 完全相同-大多数参数直接传递给该接口。但是,input=None不支持显式传递以继承父级的标准输入文件句柄。

默认情况下,此函数将以编码字节的形式返回数据。输出数据的实际编码可能取决于调用的命令,因此对文本的解码通常需要在应用程序级别进行处理。

可以通过将text,encoding,errors或universal_newlines设置True为,如“ 常用参数”和“ run()。

要还捕获结果中的标准错误,请使用 :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'

Replacing Older Functions with the subprocess Module

在本节中,“ a变为b”表示b可以替代a。
注意 如果找不到执行的程序,则本节中的所有“ a”功能都会(或多或少)无声地失败;OSError 取而代之的是“ b”替代词。
此外,如果所请求的操作产生非零的返回码,则使用的替换check_output()将失败,并显示 CalledProcessError。输出仍然可用作output引发的异常的 属性。

在以下示例中,我们假设subprocess相关功能已从模块中导入。

替换/ bin / sh shell反引号

output=`mycmd myarg`

变成:

output = check_output(["mycmd", "myarg"])

更换外壳管道

output=`dmesg | grep hda`

变成:

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。

另外,对于受信任的输入,仍然可以直接使用外壳自身的管道支持:

output=`dmesg | grep hda`

变成:

output=check_output("dmesg | grep hda", shell=True)

替换os.system()

sts = os.system("mycmd" + " myarg")
# becomes
sts = call("mycmd" + " myarg", shell=True)

一个更现实的示例如下所示:

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示例:

pid = os.spawnlp(os.P_NOWAIT, "/bin/mycmd", "mycmd", "myarg")
==>
pid = Popen(["/bin/mycmd", "myarg"]).pid

P_WAIT示例:

retcode = os.spawnlp(os.P_WAIT, "/bin/mycmd", "mycmd", "myarg")
==>
retcode = call(["/bin/mycmd", "myarg"])

矢量示例:

os.spawnvp(os.P_NOWAIT, path, args)
==>
Popen([path] + args[1:])

环境示例:

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模块中的函数
注意 如果popen2函数的cmd参数是字符串,则通过/ 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参数被替换为标准错误的说法。

stdin=PIPE并且stdout=PIPE必须指定。

popen2默认情况下会关闭所有文件描述符,但是您必须指定 close_fds=Truewith Popen来保证在所有平台或过去的Python版本上都具有这种行为。

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

subprocess.getstatusoutput(cmd )
	在shell中返回执行cmd。(exitcode, output)
	在shell中执行字符串cmdPopen.check_output()并返回2元组。使用语言环境编码;有关更多详细信息,请参见“ 常用参数”中的注释。(exitcode, output)
	从输出中删除尾随换行符。该命令的退出代码可以解释为子进程的返回代码。例:
>>> 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, '')

可用性:POSIX和Windows。

在版本3.3.4中更改:添加了Windows支持。

该函数现在返回(退出代码,输出),而不是像在Python 3.3.3和更早版本中那样返回(状态,输出)。exitcode与的值相同 returncode。

subprocess.getoutput(cmd )

返回在外壳程序中执行cmd的输出(stdout和stderr)。

与相似getstatusoutput(),除了退出代码被忽略,返回值是包含命令输出的字符串。例:
>>> subprocess.getoutput('ls /bin/ls')
	'/bin/ls'

可用性:POSIX和Windows
在版本3.3.4中更改:添加了Windows支持

在Windows上将参数序列转换为字符串

在Windows上,将args序列转换为可以使用以下规则(与MS C运行时使用的规则相对应)进行解析的字符串:

1.参数由空格分隔,空格可以是空格或制表符。

2.用双引号引起来的字符串将解释为单个参数,而不管其中包含的空格如何。可以将带引号的字符串嵌入参数中。

3.在双引号前加反斜杠的解释为文字双引号。

4.反斜杠将按字面意义进行解释,除非它们紧接在双引号之前。

5.如果反斜杠紧接在双引号之前,则每对反斜杠都将解释为文字反斜杠。如果反斜杠的数量为奇数,则最后一个反斜杠将按照规则3中的说明转义下一个双引号。


转载:https://blog.csdn.net/boyun58/article/details/101982373
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场