subprocess --- 子進(jìn)程管理?

源代碼: Lib/subprocess.py


subprocess 模塊允許你生成新的進(jìn)程,連接它們的輸入、輸出、錯(cuò)誤管道,并且獲取它們的返回碼。此模塊打算代替一些老舊的模塊與功能:

os.system
os.spawn*

在下面的段落中,你可以找到關(guān)于 subprocess 模塊如何代替這些模塊和功能的相關(guān)信息。

參見(jiàn)

PEP 324 -- 提出 subprocess 模塊的 PEP

使用 subprocess 模塊?

推薦的調(diào)用子進(jìn)程的方式是在任何它支持的用例中使用 run() 函數(shù)。對(duì)于更進(jìn)階的用例,也可以使用底層的 Popen 接口。

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)?

運(yùn)行被 arg 描述的指令. 等待指令完成, 然后返回一個(gè) CompletedProcess 實(shí)例.

以上顯示的參數(shù)僅僅是最簡(jiǎn)單的一些,下面 常用參數(shù) 描述(因此在縮寫(xiě)簽名中使用僅關(guān)鍵字標(biāo)示)。完整的函數(shù)頭和 Popen 的構(gòu)造函數(shù)一樣,此函數(shù)接受的大多數(shù)參數(shù)都被傳遞給該接口。(timeout, input, checkcapture_output 除外)。

如果 capture_output 設(shè)為 true,stdout 和 stderr 將會(huì)被捕獲。在使用時(shí),內(nèi)置的 Popen 對(duì)象將自動(dòng)用 stdout=PIPEstderr=PIPE 創(chuàng)建。stdoutstderr 參數(shù)不應(yīng)當(dāng)與 capture_output 同時(shí)提供。如果你希望捕獲并將兩個(gè)流合并在一起,使用 stdout=PIPEstderr=STDOUT 來(lái)代替 capture_output。

timeout 參數(shù)將被傳遞給 Popen.communicate()。如果發(fā)生超時(shí),子進(jìn)程將被殺死并等待。 TimeoutExpired 異常將在子進(jìn)程中斷后被拋出。

input 參數(shù)將被傳遞給 Popen.communicate() 以及子進(jìn)程的 stdin。 如果使用此參數(shù),它必須是一個(gè)字節(jié)序列。 如果指定了 encodingerrors 或者將 text 設(shè)置為 True,那么也可以是一個(gè)字符串。 當(dāng)使用此參數(shù)時(shí),在創(chuàng)建內(nèi)部 Popen 對(duì)象時(shí)將自動(dòng)帶上 stdin=PIPE,并且不能再手動(dòng)指定 stdin 參數(shù)。

如果 check 設(shè)為 True, 并且進(jìn)程以非零狀態(tài)碼退出, 一個(gè) CalledProcessError 異常將被拋出. 這個(gè)異常的屬性將設(shè)置為參數(shù), 退出碼, 以及標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤, 如果被捕獲到.

如果 encoding 或者 error 被指定, 或者 text 被設(shè)為 True, 標(biāo)準(zhǔn)輸入, 標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤的文件對(duì)象將通過(guò)指定的 encodingerrors 以文本模式打開(kāi), 否則以默認(rèn)的 io.TextIOWrapper 打開(kāi). universal_newline 參數(shù)等同于 text 并且提供了向后兼容性. 默認(rèn)情況下, 文件對(duì)象是以二進(jìn)制模式打開(kāi)的.

如果 env 不是 None, 它必須是一個(gè)字典, 為新的進(jìn)程設(shè)置環(huán)境變量; 它用于替換繼承的當(dāng)前進(jìn)程的環(huán)境的默認(rèn)行為. 它將直接被傳遞給 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 版更改: 添加了 encodingerrors 形參.

在 3.7 版更改: 添加了 text 形參, 作為 universal_newlines 的一個(gè)更好理解的別名. 添加了 capture_output 形參.

class subprocess.CompletedProcess?

run() 的返回值, 代表一個(gè)進(jìn)程已經(jīng)結(jié)束.

args?

被用作啟動(dòng)進(jìn)程的參數(shù). 可能是一個(gè)列表或字符串.

returncode?

子進(jìn)程的退出狀態(tài)碼. 通常來(lái)說(shuō), 一個(gè)為 0 的退出碼表示進(jìn)程運(yùn)行正常.

一個(gè)負(fù)值 -N 表示子進(jìn)程被信號(hào) N 中斷 (僅 POSIX).

stdout?

從子進(jìn)程捕獲到的標(biāo)準(zhǔn)輸出. 一個(gè)字節(jié)序列, 或一個(gè)字符串, 如果 run() 是設(shè)置了 encoding, errors 或者 text=True 來(lái)運(yùn)行的. 如果未有捕獲, 則為 None.

如果你通過(guò) stderr=subprocess.STDOUT 運(yùn)行進(jìn)程,標(biāo)準(zhǔn)輸入和標(biāo)準(zhǔn)錯(cuò)誤將被組合在這個(gè)屬性中,并且 stderr 將為 None

stderr?

捕獲到的子進(jìn)程的標(biāo)準(zhǔn)錯(cuò)誤. 一個(gè)字節(jié)序列, 或者一個(gè)字符串, 如果 run() 是設(shè)置了參數(shù) encoding, errors 或者 text=True 運(yùn)行的. 如果未有捕獲, 則為 None.

check_returncode()?

如果 returncode 非零, 拋出 CalledProcessError.

3.5 新版功能.

subprocess.DEVNULL?

可被 Popenstdin, stdout 或者 stderr 參數(shù)使用的特殊值, 表示使用特殊文件 os.devnull.

3.3 新版功能.

subprocess.PIPE?

可被 Popenstdin, stdout 或者 stderr 參數(shù)使用的特殊值, 表示打開(kāi)標(biāo)準(zhǔn)流的管道. 常用于 Popen.communicate().

subprocess.STDOUT?

可被 Popenstdin , stdout 或者 stderr 參數(shù)使用的特殊值, 表示標(biāo)準(zhǔn)錯(cuò)誤與標(biāo)準(zhǔn)輸出使用同一句柄。

exception subprocess.SubprocessError?

此模塊的其他異常的基類(lèi)。

3.3 新版功能.

exception subprocess.TimeoutExpired?

SubprocessError 的子類(lèi),等待子進(jìn)程的過(guò)程中發(fā)生超時(shí)時(shí)被拋出。

cmd?

用于創(chuàng)建子進(jìn)程的指令。

timeout?

超時(shí)秒數(shù)。

output?

子進(jìn)程的輸出, 如果被 run()check_output() 捕獲。否則為 None。

stdout?

對(duì) output 的別名,對(duì)應(yīng)的有 stderr

stderr?

子進(jìn)程的標(biāo)準(zhǔn)錯(cuò)誤輸出,如果被 run() 捕獲。 否則為 None。

3.3 新版功能.

在 3.5 版更改: 添加了 stdoutstderr 屬性。

exception subprocess.CalledProcessError?

Subclass of SubprocessError, raised when a process run by check_call(), check_output(), or run() (with check=True) returns a non-zero exit status.

returncode?

子進(jìn)程的退出狀態(tài)。如果程序由一個(gè)信號(hào)終止,這將會(huì)被設(shè)為一個(gè)負(fù)的信號(hào)碼。

cmd?

用于創(chuàng)建子進(jìn)程的指令。

output?

子進(jìn)程的輸出, 如果被 run()check_output() 捕獲。否則為 None。

stdout?

對(duì) output 的別名,對(duì)應(yīng)的有 stderr。

stderr?

子進(jìn)程的標(biāo)準(zhǔn)錯(cuò)誤輸出,如果被 run() 捕獲。 否則為 None

在 3.5 版更改: 添加了 stdoutstderr 屬性。

常用參數(shù)?

為了支持豐富的使用案例, Popen 的構(gòu)造函數(shù)(以及方便的函數(shù))接受大量可選的參數(shù)。對(duì)于大多數(shù)典型的用例,許多參數(shù)可以被安全地留以它們的默認(rèn)值。通常需要的參數(shù)有:

args 被所有調(diào)用需要,應(yīng)當(dāng)為一個(gè)字符串,或者一個(gè)程序參數(shù)序列。提供一個(gè)參數(shù)序列通常更好,它可以更小心地使用參數(shù)中的轉(zhuǎn)義字符以及引用(例如允許文件名中的空格)。如果傳遞一個(gè)簡(jiǎn)單的字符串,則 shell 參數(shù)必須為 True (見(jiàn)下文)或者該字符串中將被運(yùn)行的程序名必須用簡(jiǎn)單的命名而不指定任何參數(shù)。

stdin, stdout and stderr specify the executed program's standard input, standard output and standard error file handles, respectively. Valid values are PIPE, DEVNULL, an existing file descriptor (a positive integer), an existing file object with a valid file descriptor, and None. PIPE indicates that a new pipe to the child should be created. DEVNULL indicates that the special file os.devnull will be used. With the default settings of None, no redirection will occur; the child's file handles will be inherited from the parent. Additionally, stderr can be STDOUT, which indicates that the stderr data from the child process should be captured into the same file handle as for stdout.

如果 encodingerrors 被指定,或者 text (也名為 universal_newlines)為真,則文件對(duì)象 stdinstdoutstderr 將會(huì)使用在此次調(diào)用中指定的 encodingerrors 以文本模式打開(kāi)或者為默認(rèn)的 io.TextIOWrapper。

當(dāng)構(gòu)造函數(shù)的 newline 參數(shù)為 None 時(shí)。對(duì)于 stdin, 輸入的換行符 '\n' 將被轉(zhuǎn)換為默認(rèn)的換行符 os.linesep。對(duì)于 stdoutstderr, 所有輸出的換行符都被轉(zhuǎn)換為 '\n'。更多信息,查看 io.TextIOWrapper 類(lèi)的文檔。

如果文本模式未被使用, stdin, stdoutstderr 將會(huì)以二進(jìn)制流模式打開(kāi)。沒(méi)有編碼與換行符轉(zhuǎn)換發(fā)生。

3.6 新版功能: 添加了 encodingerrors 形參。

3.7 新版功能: 添加了 text 形參作為 universal_newlines 的別名。

備注

文件對(duì)象 Popen.stdin 、 Popen.stdoutPopen.stderr 的換行符屬性不會(huì)被 Popen.communicate() 方法更新。

如果 shell 設(shè)為 True,,則使用 shell 執(zhí)行指定的指令。如果您主要使用 Python 增強(qiáng)的控制流(它比大多數(shù)系統(tǒng) shell 提供的強(qiáng)大),并且仍然希望方便地使用其他 shell 功能,如 shell 管道、文件通配符、環(huán)境變量展開(kāi)以及 ~ 展開(kāi)到用戶(hù)家目錄,這將非常有用。但是,注意 Python 自己也實(shí)現(xiàn)了許多類(lèi)似 shell 的特性(例如 glob, fnmatch, os.walk(), os.path.expandvars(), os.path.expanduser()shutil)。

在 3.3 版更改: 當(dāng) universal_newline 被設(shè)為 True,則類(lèi)使用 locale.getpreferredencoding(False) 編碼來(lái)代替 locale.getpreferredencoding()。關(guān)于它們的區(qū)別的更多信息,見(jiàn) io.TextIOWrapper。

備注

在使用 shell=True 之前, 請(qǐng)閱讀 Security Considerations 段落。

這些選項(xiàng)以及所有其他選項(xiàng)在 Popen 構(gòu)造函數(shù)文檔中有更詳細(xì)的描述。

Popen 構(gòu)造函數(shù)?

此模塊的底層的進(jìn)程創(chuàng)建與管理由 Popen 類(lèi)處理。它提供了很大的靈活性,因此開(kāi)發(fā)者能夠處理未被便利函數(shù)覆蓋的不常見(jiàn)用例。

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=(), *, group=None, extra_groups=None, user=None, umask=- 1, encoding=None, errors=None, text=None, pipesize=- 1, process_group=None)?

在一個(gè)新的進(jìn)程中執(zhí)行子程序。 在 POSIX 上,該類(lèi)會(huì)使用類(lèi)似于 os.execvpe() 的行為來(lái)執(zhí)行子程序。 在 Windows 上,該類(lèi)會(huì)使用 Windows CreateProcess() 函數(shù)。 Popen 的參數(shù)如下。

args 應(yīng)當(dāng)是一個(gè)程序參數(shù)的序列或者是一個(gè)單獨(dú)的字符串或 path-like object。 默認(rèn)情況下,如果 args 是序列則要運(yùn)行的程序?yàn)?args 中的第一項(xiàng)。 如果 args 是字符串,則其解讀依賴(lài)于具體平臺(tái),如下所述。 請(qǐng)查看 shellexecutable 參數(shù)了解其與默認(rèn)行為的其他差異。 除非另有說(shuō)明,否則推薦以序列形式傳入 args。

警告

為了最大化可靠性,請(qǐng)使用可執(zhí)行文件的完整限定路徑。 要在 PATH 中搜索一個(gè)未限定名稱(chēng),請(qǐng)使用 shutil.which()。 在所有平臺(tái)上,傳入 sys.executable 是再次啟動(dòng)當(dāng)前 Python 解釋器的推薦方式,并請(qǐng)使用 -m 命令行格式來(lái)啟動(dòng)已安裝的模塊。

對(duì) executable (或 args 的第一項(xiàng)) 路徑的解析方式依賴(lài)于具體平臺(tái)。 對(duì)于 POSIX,請(qǐng)參閱 os.execvpe(),并要注意當(dāng)解析或搜索可執(zhí)行文件路徑時(shí),cwd 會(huì)覆蓋當(dāng)前工作目錄而 env 可以覆蓋 PATH 環(huán)境變量。 對(duì)于 Windows,請(qǐng)參閱 lpApplicationName 的文檔以及 lpCommandLine 形參 (傳給 WinAPI CreateProcess),并要注意當(dāng)解析或搜索可執(zhí)行文件路徑時(shí)如果傳入 shell=False,則 cwd 不會(huì)覆蓋當(dāng)前工作目錄而 env 無(wú)法覆蓋 PATH 環(huán)境變量。 使用完整路徑可避免所有這些變化情況。

向外部函數(shù)傳入序列形式參數(shù)的一個(gè)例子如下:

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

在 POSIX,如果 args 是一個(gè)字符串,此字符串被作為將被執(zhí)行的程序的命名或路徑解釋。但是,只有在不傳遞任何參數(shù)給程序的情況下才能這么做。

備注

將 shell 命令拆分為參數(shù)序列的方式可能并不很直觀,特別是在復(fù)雜的情況下。 shlex.split() 可以演示如何確定 args 適當(dāng)?shù)牟鸱中问?

>>>
>>> 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 中的空格分隔的選項(xiàng)(例如 -input)和參數(shù)(例如 eggs.txt )位于分開(kāi)的列表元素中,而在需要時(shí)使用引號(hào)或反斜杠轉(zhuǎn)義的參數(shù)在 shell (例如包含空格的文件名或上面顯示的 echo 命令)是單獨(dú)的列表元素。

在 Windows,如果 args 是一個(gè)序列,他將通過(guò)一個(gè)在 在 Windows 上將參數(shù)列表轉(zhuǎn)換為一個(gè)字符串 描述的方式被轉(zhuǎn)換為一個(gè)字符串。這是因?yàn)榈讓拥?CreateProcess() 只處理字符串。

在 3.6 版更改: 在 POSIX 上如果 shellFalse 并且序列包含路徑類(lèi)對(duì)象則 args 形參可以接受一個(gè) path-like object。

在 3.8 版更改: 如果在Windows 上 shellFalse 并且序列包含字節(jié)串和路徑類(lèi)對(duì)象則 args 形參可以接受一個(gè) path-like object。

參數(shù) shell (默認(rèn)為 False)指定是否使用 shell 執(zhí)行程序。如果 shellTrue,更推薦將 args 作為字符串傳遞而非序列。

在 POSIX,當(dāng) shell=True, shell 默認(rèn)為 /bin/sh。如果 args 是一個(gè)字符串,此字符串指定將通過(guò) shell 執(zhí)行的命令。這意味著字符串的格式必須和在命令提示符中所輸入的完全相同。這包括,例如,引號(hào)和反斜杠轉(zhuǎn)義包含空格的文件名。如果 args 是一個(gè)序列,第一項(xiàng)指定了命令,另外的項(xiàng)目將作為傳遞給 shell (而非命令) 的參數(shù)對(duì)待。也就是說(shuō), Popen 等同于:

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

在 Windows,使用 shell=True,環(huán)境變量 COMSPEC 指定了默認(rèn) shell。在 Windows 你唯一需要指定 shell=True 的情況是你想要執(zhí)行內(nèi)置在 shell 中的命令(例如 dir 或者 copy)。在運(yùn)行一個(gè)批處理文件或者基于控制臺(tái)的可執(zhí)行文件時(shí),不需要 shell=True。

備注

在使用 shell=True 之前, 請(qǐng)閱讀 Security Considerations 段落。

bufsize 將在 open() 函數(shù)創(chuàng)建了 stdin/stdout/stderr 管道文件對(duì)象時(shí)作為對(duì)應(yīng)的參數(shù)供應(yīng):

  • 0 表示不使用緩沖區(qū) (讀取與寫(xiě)入是一個(gè)系統(tǒng)調(diào)用并且可以返回短內(nèi)容)

  • 1 表示行緩沖(只有 universal_newlines=True 時(shí)才有用,例如,在文本模式中)

  • 任何其他正值表示使用一個(gè)約為對(duì)應(yīng)大小的緩沖區(qū)

  • 負(fù)的 bufsize (默認(rèn))表示使用系統(tǒng)默認(rèn)的 io.DEFAULT_BUFFER_SIZE。

在 3.3.1 版更改: bufsize 現(xiàn)在默認(rèn)為 -1 來(lái)啟用緩沖,以符合大多數(shù)代碼所期望的行為。在 Python 3.2.4 和 3.3.1 之前的版本中,它錯(cuò)誤地將默認(rèn)值設(shè)為了為 0,這是無(wú)緩沖的并且允許短讀取。這是無(wú)意的,并且與大多數(shù)代碼所期望的 Python 2 的行為不一致。

executable 參數(shù)指定一個(gè)要執(zhí)行的替換程序。這很少需要。當(dāng) shell=Trueexecutable 替換 args 指定運(yùn)行的程序。但是,原始的 args 仍然被傳遞給程序。大多數(shù)程序?qū)⒈?args 指定的程序作為命令名對(duì)待,這可以與實(shí)際運(yùn)行的程序不同。在 POSIX, args 名作為實(shí)際調(diào)用程序中可執(zhí)行文件的顯示名稱(chēng),例如 ps。如果 shell=True,在 POSIX, executable 參數(shù)指定用于替換默認(rèn) shell /bin/sh 的 shell。

在 3.6 版更改: 在POSIX 上 executable 形參可以接受一個(gè) path-like object。

在 3.8 版更改: 在Windows 上 executable 形參可以接受一個(gè)字節(jié)串和 path-like object。

stdin, stdout and stderr specify the executed program's standard input, standard output and standard error file handles, respectively. Valid values are PIPE, DEVNULL, an existing file descriptor (a positive integer), an existing file object with a valid file descriptor, and None. PIPE indicates that a new pipe to the child should be created. DEVNULL indicates that the special file os.devnull will be used. With the default settings of None, no redirection will occur; the child's file handles will be inherited from the parent. Additionally, stderr can be STDOUT, which indicates that the stderr data from the applications should be captured into the same file handle as for stdout.

如果 preexec_fn 被設(shè)為一個(gè)可調(diào)用對(duì)象,此對(duì)象將在子進(jìn)程剛創(chuàng)建時(shí)被調(diào)用。(僅 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 形參在子解釋器中已不再受支持。 在子解釋器中使用此形參將引發(fā) RuntimeError。 這個(gè)新限制可能會(huì)影響部署在 mod_wsgi, uWSGI 和其他嵌入式環(huán)境中的應(yīng)用。

如果 close_fds 為真,所有文件描述符除了 0, 1, 2 之外都會(huì)在子進(jìn)程執(zhí)行前關(guān)閉。而當(dāng) close_fds 為假時(shí),文件描述符遵守它們繼承的標(biāo)志,如 文件描述符的繼承 所述。

在 Windows,如果 close_fds 為真, 則子進(jìn)程不會(huì)繼承任何句柄,除非在 STARTUPINFO.IpAttributeListhandle_list 的鍵中顯式傳遞,或者通過(guò)標(biāo)準(zhǔn)句柄重定向傳遞。

在 3.2 版更改: close_fds 的默認(rèn)值已經(jīng)從 False 修改為上述值。

在 3.7 版更改: 在 Windows,當(dāng)重定向標(biāo)準(zhǔn)句柄時(shí) close_fds 的默認(rèn)值從 False 變?yōu)?True。現(xiàn)在重定向標(biāo)準(zhǔn)句柄時(shí)有可能設(shè)置 close_fdsTrue。(標(biāo)準(zhǔn)句柄指三個(gè) stdio 的句柄)

pass_fds 是一個(gè)可選的在父子進(jìn)程間保持打開(kāi)的文件描述符序列。提供任何 pass_fds 將強(qiáng)制 close_fdsTrue。(僅 POSIX)

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

如果 cwd 不為 None,此函數(shù)在執(zhí)行子進(jìn)程前會(huì)將當(dāng)前工作目錄改為 cwd。 cwd 可以是一個(gè)字符串、字節(jié)串或 路徑類(lèi)對(duì)象。 在 POSIX 上,如果可執(zhí)行文件路徑為相對(duì)路徑則此函數(shù)會(huì)相對(duì)于 cwd 來(lái)查找 executable (或 args 的第一項(xiàng))。

在 3.6 版更改: 在 POSIX 上 cwd 形參接受一個(gè) path-like object

在 3.7 版更改: 在 Windows 上 cwd 形參接受一個(gè) path-like object

在 3.8 版更改: 在 Windows 上 cwd 形參接受一個(gè)字節(jié)串對(duì)象。

 如果 restore_signals 為 true(默認(rèn)值),則 Python 設(shè)置為 SIG_IGN 的所有信號(hào)將在 exec 之前的子進(jìn)程中恢復(fù)為 SIG_DFL。目前,這包括 SIGPIPE ,SIGXFZ 和 SIGXFSZ 信號(hào)。 (僅 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() 系統(tǒng)調(diào)用將于子進(jìn)程執(zhí)行之前在下級(jí)進(jìn)程中進(jìn)行。 如果所提供的值為一個(gè)字符串,將通過(guò) grp.getgrnam() 來(lái)查找它,并將使用 gr_gid 中的值。 如果該值為一個(gè)整數(shù),它將被原樣傳遞。 (POSIX 專(zhuān)屬)

可用性: POSIX

3.9 新版功能.

如果 extra_groups 不為 None,則 setgroups() 系統(tǒng)調(diào)用將于子進(jìn)程之前在下級(jí)進(jìn)程中進(jìn)行。 在 extra_groups 中提供的字符串將通過(guò) grp.getgrnam() 來(lái)查找,并將使用 gr_gid 中的值。 整數(shù)值將被原樣傳遞。 (POSIX 專(zhuān)屬)

可用性: POSIX

3.9 新版功能.

如果 user 不為 None,則 setreuid() 系統(tǒng)調(diào)用將于子進(jìn)程執(zhí)行之前在下級(jí)進(jìn)程中進(jìn)行。 如果所提供的值為一個(gè)字符串,將通過(guò) pwd.getpwnam() 來(lái)查找它,并將使用 pw_uid 中的值。 如果該值為一個(gè)整數(shù),它將被原樣傳遞。 (POSIX 專(zhuān)屬)

可用性: POSIX

3.9 新版功能.

如果 umask 不為負(fù)值,則 umask() 系統(tǒng)調(diào)用將在子進(jìn)程執(zhí)行之前在下級(jí)進(jìn)程中進(jìn)行。

可用性: POSIX

3.9 新版功能.

如果 env 不為 None,則必須為一個(gè)為新進(jìn)程定義了環(huán)境變量的字典;這些用于替換繼承的當(dāng)前進(jìn)程環(huán)境的默認(rèn)行為。

備注

如果指定, env 必須提供所有被子進(jìn)程需求的變量。在 Windows,為了運(yùn)行一個(gè) side-by-side assembly ,指定的 env 必須 包含一個(gè)有效的 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 常用參數(shù). 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 新版功能: encodingerrors 被添加。

3.7 新版功能: text 作為 universal_newlines 的一個(gè)更具可讀性的別名被添加。

如果給出, startupinfo 將是一個(gè)將被傳遞給底層的 CreateProcess 函數(shù)的 STARTUPINFO 對(duì)象。 creationflags,如果給出,可以是一個(gè)或多個(gè)以下標(biāo)志之一:

當(dāng) PIPE 被用作 stdin, stdoutstderr 時(shí) pipesize 可被用于改變管道的大小。 管道的大小僅會(huì)在受支持的平臺(tái)上被改變(當(dāng)撰寫(xiě)本文檔時(shí)只有 Linux 支持)。 其他平臺(tái)將忽略此形參。

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

Popen 對(duì)象支持通過(guò) with 語(yǔ)句作為上下文管理器,在退出時(shí)關(guān)閉文件描述符并等待進(jìn)程:

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

引發(fā)一個(gè) 審計(jì)事件 subprocess.Popen,附帶參數(shù) executable, args, cwd, env。

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

在 3.6 版更改: 現(xiàn)在,如果 Popen 析構(gòu)時(shí)子進(jìn)程仍然在運(yùn)行,則析構(gòu)器會(huì)發(fā)送一個(gè) ResourceWarning 警告。

在 3.8 版更改: 在某些情況下 Popen 可以使用 os.posix_spawn() 以獲得更好的性能。在適用于 Linux 的 Windows 子系統(tǒng)和 QEMU 用戶(hù)模擬器上,使用 os.posix_spawn() 的 Popen 構(gòu)造器不再會(huì)因找不到程序等錯(cuò)誤而引發(fā)異常,而是上下級(jí)進(jìn)程失敗并返回一個(gè)非零的 returncode

異常?

在子進(jìn)程中拋出的異常,在新的進(jìn)程開(kāi)始執(zhí)行前,將會(huì)被再次在父進(jìn)程中拋出。

被引發(fā)的最一般異常是 OSError。 例如這會(huì)在嘗試執(zhí)行一個(gè)不存在的文件時(shí)發(fā)生。 應(yīng)用程序應(yīng)當(dāng)為 OSError 異常做好準(zhǔn)備。 請(qǐng)注意,如果 shell=True,則 OSError 僅會(huì)在未找到選定的 shell 本身時(shí)被引發(fā)。 要確定 shell 是否未找到所請(qǐng)求的應(yīng)用程序,必須檢查來(lái)自子進(jìn)程的返回碼或輸出。

如果 Popen 調(diào)用時(shí)有無(wú)效的參數(shù),則一個(gè) ValueError 將被拋出。

check_call()check_output() 在調(diào)用的進(jìn)程返回非零退出碼時(shí)將拋出 CalledProcessError。

所有接受 timeout 形參的函數(shù)與方法,例如 call()Popen.communicate() 將會(huì)在進(jìn)程退出前超時(shí)到期時(shí)拋出 TimeoutExpired。

此模塊中定義的異常都繼承自 SubprocessError。

3.3 新版功能: 基類(lèi) SubprocessError 被添加。

安全考量?

不同于某些其他的 popen 函數(shù),這個(gè)實(shí)現(xiàn)絕不會(huì)隱式地調(diào)用系統(tǒng) shell。 這意味著所有字符,包括 shell 元字符,都可以安全地被傳遞給子進(jìn)程。 如果 shell 通過(guò) shell=True 被顯式地發(fā)起調(diào)用,則應(yīng)用程序有責(zé)任確保所有空白符和元字符被適當(dāng)?shù)剞D(zhuǎn)義以避免 shell 注入 漏洞。 在 某些平臺(tái) 上,可以使用 shlex.quote() 來(lái)執(zhí)行這樣的轉(zhuǎn)義。

Popen 對(duì)象?

Popen 類(lèi)的實(shí)例擁有以下方法:

Popen.poll()?

檢查子進(jìn)程是否已被終止。設(shè)置并返回 returncode 屬性。否則返回 None。

Popen.wait(timeout=None)?

等待子進(jìn)程被終止。設(shè)置并返回 returncode 屬性。

如果進(jìn)程在 timeout 秒后未中斷,拋出一個(gè) TimeoutExpired 異常,可以安全地捕獲此異常并重新等待。

備注

當(dāng) stdout=PIPE 或者 stderr=PIPE 并且子進(jìn)程產(chǎn)生了足以阻塞 OS 管道緩沖區(qū)接收更多數(shù)據(jù)的輸出到管道時(shí),將會(huì)發(fā)生死鎖。當(dāng)使用管道時(shí)用 Popen.communicate() 來(lái)規(guī)避它。

備注

此函數(shù)使用了一個(gè) busy loop (非阻塞調(diào)用以及短睡眠) 實(shí)現(xiàn)。使用 asyncio 模塊進(jìn)行異步等待: 參閱 asyncio.create_subprocess_exec。

在 3.3 版更改: timeout 被添加

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

與進(jìn)程交互:將數(shù)據(jù)發(fā)送到 stdin。 從 stdout 和 stderr 讀取數(shù)據(jù),直到抵達(dá)文件結(jié)尾。 等待進(jìn)程終止并設(shè)置 returncode 屬性。 可選的 input 參數(shù)應(yīng)為要發(fā)送到下級(jí)進(jìn)程的數(shù)據(jù),或者如果沒(méi)有要發(fā)送到下級(jí)進(jìn)程的數(shù)據(jù)則為 None。 如果流是以文本模式打開(kāi)的,則 input 必須為字符串。 在其他情況下,它必須為字節(jié)串。

communicate() 返回一個(gè) (stdout_data, stderr_data) 元組。如果文件以文本模式打開(kāi)則為字符串;否則字節(jié)。

注意如果你想要向進(jìn)程的 stdin 傳輸數(shù)據(jù),你需要通過(guò) stdin=PIPE 創(chuàng)建此 Popen 對(duì)象。類(lèi)似的,要從結(jié)果元組獲取任何非 None 值,你同樣需要設(shè)置 stdout=PIPE 或者 stderr=PIPE。

如果進(jìn)程在 timeout 秒后未終止,一個(gè) TimeoutExpired 異常將被拋出。捕獲此異常并重新等待將不會(huì)丟失任何輸出。

如果超時(shí)到期,子進(jìn)程不會(huì)被殺死,所以為了正確清理一個(gè)行為良好的應(yīng)用程序應(yīng)該殺死子進(jìn)程并完成通訊。

proc = subprocess.Popen(...)
try:
    outs, errs = proc.communicate(timeout=15)
except TimeoutExpired:
    proc.kill()
    outs, errs = proc.communicate()

備注

內(nèi)存里數(shù)據(jù)讀取是緩沖的,所以如果數(shù)據(jù)尺寸過(guò)大或無(wú)限,不要使用此方法。

在 3.3 版更改: timeout 被添加

Popen.send_signal(signal)?

將信號(hào) signal 發(fā)送給子進(jìn)程。

如果進(jìn)程已完成則不做任何操作。

備注

在 Windows, SIGTERM 是一個(gè) terminate() 的別名。 CTRL_C_EVENT 和 CTRL_BREAK_EVENT 可以被發(fā)送給以包含 CREATE_NEW_PROCESScreationflags 形參啟動(dòng)的進(jìn)程。

Popen.terminate()?

停止子進(jìn)程。 在 POSIX 操作系統(tǒng)上,此方法會(huì)發(fā)送 SIGTERM 給子進(jìn)程。 在 Windows 上則會(huì)調(diào)用 Win32 API 函數(shù) TerminateProcess() 來(lái)停止子進(jìn)程。

Popen.kill()?

殺死子進(jìn)程。 在 POSIX 操作系統(tǒng)上,此函數(shù)會(huì)發(fā)送 SIGKILL 給子進(jìn)程。 在 Windows 上 kill() 則是 terminate() 的別名。

以下屬性也是可用的:

Popen.args?

args 參數(shù)傳遞給 Popen -- 一個(gè)程序參數(shù)的序列或者一個(gè)簡(jiǎn)單字符串。

3.3 新版功能.

Popen.stdin?

如果 stdin 參數(shù)為 PIPE,此屬性是一個(gè)類(lèi)似 open() 返回的可寫(xiě)的流對(duì)象。如果 encodingerrors 參數(shù)被指定或者 universal_newlines 參數(shù)為 True,則此流是一個(gè)文本流,否則是字節(jié)流。如果 stdin 參數(shù)非 PIPE, 此屬性為 None。

Popen.stdout?

如果 stdout 參數(shù)是 PIPE,此屬性是一個(gè)類(lèi)似 open() 返回的可讀流。從流中讀取子進(jìn)程提供的輸出。如果 encodingerrors 參數(shù)被指定或者 universal_newlines 參數(shù)為 True,此流為文本流,否則為字節(jié)流。如果 stdout 參數(shù)非 PIPE,此屬性為 None

Popen.stderr?

如果 stderr 參數(shù)是 PIPE,此屬性是一個(gè)類(lèi)似 open() 返回的可讀流。從流中讀取子進(jìn)程提供的輸出。如果 encodingerrors 參數(shù)被指定或者 universal_newlines 參數(shù)為 True,此流為文本流,否則為字節(jié)流。如果 stderr 參數(shù)非 PIPE,此屬性為 None。

警告

使用 communicate() 而非 .stdin.write, .stdout.read 或者 .stderr.read 來(lái)避免由于任意其他 OS 管道緩沖區(qū)被子進(jìn)程填滿阻塞而導(dǎo)致的死鎖。

Popen.pid?

子進(jìn)程的進(jìn)程號(hào)。

注意如果你設(shè)置了 shell 參數(shù)為 True,則這是生成的子 shell 的進(jìn)程號(hào)。

Popen.returncode?

此進(jìn)程的退出碼,由 poll()wait() 設(shè)置(以及直接由 communicate() 設(shè)置)。一個(gè) None 值 表示此進(jìn)程仍未結(jié)束。

一個(gè)負(fù)值 -N 表示子進(jìn)程被信號(hào) N 中斷 (僅 POSIX).

Windows Popen 助手?

STARTUPINFO 類(lèi)和以下常數(shù)僅在 Windows 有效。

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

Popen 創(chuàng)建時(shí)部分支持 Windows 的 STARTUPINFO 結(jié)構(gòu)。接下來(lái)的屬性?xún)H能通過(guò)關(guān)鍵詞參數(shù)設(shè)置。

在 3.7 版更改: 僅關(guān)鍵詞參數(shù)支持被加入。

dwFlags?

一個(gè)位字段,用于確定進(jìn)程在創(chuàng)建窗口時(shí)是否使用某些 STARTUPINFO 屬性。

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

如果 dwFlags 被指定為 STARTF_USESTDHANDLES,則此屬性是進(jìn)程的標(biāo)準(zhǔn)輸入句柄,如果 STARTF_USESTDHANDLES 未指定,則默認(rèn)的標(biāo)準(zhǔn)輸入是鍵盤(pán)緩沖區(qū)。

hStdOutput?

如果 dwFlags 被指定為 STARTF_USESTDHANDLES,則此屬性是進(jìn)程的標(biāo)準(zhǔn)輸出句柄。除此之外,此此屬性將被忽略并且默認(rèn)標(biāo)準(zhǔn)輸出是控制臺(tái)窗口緩沖區(qū)。

hStdError?

如果 dwFlags 被指定為 STARTF_USESTDHANDLES,則此屬性是進(jìn)程的標(biāo)準(zhǔn)錯(cuò)誤句柄。除此之外,此屬性將被忽略并且默認(rèn)標(biāo)準(zhǔn)錯(cuò)誤為控制臺(tái)窗口的緩沖區(qū)。

wShowWindow?

如果 dwFlags 指定了 STARTF_USESHOWWINDOW,此屬性可為能被指定為 函數(shù) ShowWindow 的nCmdShow 的形參的任意值,除了 SW_SHOWDEFAULT。如此之外,此屬性被忽略。

SW_HIDE 被提供給此屬性。它在 Popenshell=True 調(diào)用時(shí)使用。

lpAttributeList?

STARTUPINFOEX 給出的用于進(jìn)程創(chuàng)建的額外屬性字典,參閱 UpdateProcThreadAttribute。

支持的屬性:

handle_list

將被繼承的句柄的序列。如果非空, close_fds 必須為 true。

當(dāng)傳遞給 Popen 構(gòu)造函數(shù)時(shí),這些句柄必須暫時(shí)地能被 os.set_handle_inheritable() 繼承,否則 OSError 將以 Windows error ERROR_INVALID_PARAMETER (87) 拋出。

警告

在多線程進(jìn)程中,請(qǐng)謹(jǐn)慎使用,以便在將此功能與對(duì)繼承所有句柄的其他進(jìn)程創(chuàng)建函數(shù)——例如 os.system() 的并發(fā)調(diào)用——相結(jié)合時(shí),避免泄漏標(biāo)記為可繼承的句柄。這也應(yīng)用于臨時(shí)性創(chuàng)建可繼承句柄的標(biāo)準(zhǔn)句柄重定向。

3.7 新版功能.

Windows 常數(shù)?

subprocess 模塊曝出以下常數(shù)。

subprocess.STD_INPUT_HANDLE?

標(biāo)準(zhǔn)輸入設(shè)備,這是控制臺(tái)輸入緩沖區(qū) CONIN$

subprocess.STD_OUTPUT_HANDLE?

標(biāo)準(zhǔn)輸出設(shè)備。最初,這是活動(dòng)控制臺(tái)屏幕緩沖區(qū) CONOUT$。

subprocess.STD_ERROR_HANDLE?

標(biāo)準(zhǔn)錯(cuò)誤設(shè)備。最初,這是活動(dòng)控制臺(tái)屏幕緩沖區(qū) CONOUT$。

subprocess.SW_HIDE?

隱藏窗口。另一個(gè)窗口將被激活。

subprocess.STARTF_USESTDHANDLES?

指明 STARTUPINFO.hStdInput, STARTUPINFO.hStdOutputSTARTUPINFO.hStdError 屬性包含額外的信息。

subprocess.STARTF_USESHOWWINDOW?

指明 STARTUPINFO.wShowWindow 屬性包含額外的信息。

subprocess.CREATE_NEW_CONSOLE?

新的進(jìn)程將有新的控制臺(tái),而不是繼承父進(jìn)程的(默認(rèn))控制臺(tái)。

subprocess.CREATE_NEW_PROCESS_GROUP?

用于指明將創(chuàng)建一個(gè)新的進(jìn)程組的 Popen creationflags 形參。 這個(gè)旗標(biāo)對(duì)于在子進(jìn)程上使用 os.kill() 來(lái)說(shuō)是必須的。

如果指定了 CREATE_NEW_CONSOLE 則這個(gè)旗標(biāo)會(huì)被忽略。

subprocess.ABOVE_NORMAL_PRIORITY_CLASS?

用于指明一個(gè)新進(jìn)程將具有高于平均的優(yōu)先級(jí)的 Popen creationflags 形參。

3.7 新版功能.

subprocess.BELOW_NORMAL_PRIORITY_CLASS?

用于指明一個(gè)新進(jìn)程將具有低于平均的優(yōu)先級(jí)的 Popen creationflags 形參。

3.7 新版功能.

subprocess.HIGH_PRIORITY_CLASS?

用于指明一個(gè)新進(jìn)程將具有高優(yōu)先級(jí)的 Popen creationflags 形參。

3.7 新版功能.

subprocess.IDLE_PRIORITY_CLASS?

用于指明一個(gè)新進(jìn)程將具有空閑(最低)優(yōu)先級(jí)的 Popen creationflags 形參。

3.7 新版功能.

subprocess.NORMAL_PRIORITY_CLASS?

用于指明一個(gè)新進(jìn)程將具有正常(默認(rèn))優(yōu)先級(jí)的 Popen creationflags 形參。

3.7 新版功能.

subprocess.REALTIME_PRIORITY_CLASS?

用于指明一個(gè)新進(jìn)程將具有實(shí)時(shí)優(yōu)先級(jí)的 Popen creationflags 形參。 你應(yīng)當(dāng)幾乎永遠(yuǎn)不使用 REALTIME_PRIORITY_CLASS,因?yàn)檫@會(huì)中斷管理鼠標(biāo)輸入、鍵盤(pán)輸入以及后臺(tái)磁盤(pán)刷新的系統(tǒng)線程。 這個(gè)類(lèi)只適用于直接與硬件“對(duì)話”,或者執(zhí)行短暫任務(wù)具有受限中斷的應(yīng)用。

3.7 新版功能.

subprocess.CREATE_NO_WINDOW?

指明一個(gè)新進(jìn)程將不會(huì)創(chuàng)建窗口的 Popen creationflags 形參。

3.7 新版功能.

subprocess.DETACHED_PROCESS?

指明一個(gè)新進(jìn)程將不會(huì)繼承其父控制臺(tái)的 Popen creationflags 形參。 這個(gè)值不能與 CREATE_NEW_CONSOLE 一同使用。

3.7 新版功能.

subprocess.CREATE_DEFAULT_ERROR_MODE?

指明一個(gè)新進(jìn)程不會(huì)繼承調(diào)用方進(jìn)程的錯(cuò)誤模式的 Popen creationflags 形參。 新進(jìn)程會(huì)轉(zhuǎn)為采用默認(rèn)的錯(cuò)誤模式。 這個(gè)特性特別適用于運(yùn)行時(shí)禁用硬錯(cuò)誤的多線程 shell 應(yīng)用。

3.7 新版功能.

subprocess.CREATE_BREAKAWAY_FROM_JOB?

指明一個(gè)新進(jìn)程不會(huì)關(guān)聯(lián)到任務(wù)的 Popen creationflags 形參。

3.7 新版功能.

較舊的高階 API?

在 Python 3.5 之前,這三個(gè)函數(shù)組成了 subprocess 的高階 API。 現(xiàn)在你可以在許多情況下使用 run(),但有大量現(xiàn)在代碼仍會(huì)調(diào)用這些函數(shù)。

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

運(yùn)行由 args 所描述的命令。 等待命令完成,然后返回 returncode 屬性。

需要捕獲 stdout 或 stderr 的代碼應(yīng)當(dāng)改用 run():

run(...).returncode

要屏蔽 stdout 或 stderr,可提供 DEVNULL 這個(gè)值。

上面顯示的參數(shù)只是常見(jiàn)的一些。 完整的函數(shù)簽名與 Popen 構(gòu)造器的相同 —— 此函數(shù)會(huì)將所提供的 timeout 之外的全部參數(shù)直接傳遞給目標(biāo)接口。

備注

請(qǐng)不要在此函數(shù)中使用 stdout=PIPEstderr=PIPE。 如果子進(jìn)程向管道生成了足以填滿 OS 管理緩沖區(qū)的輸出而管道還未被讀取時(shí)它將會(huì)阻塞。

在 3.3 版更改: timeout 被添加

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

Run command with arguments. Wait for command to complete. If the return code was zero then return, otherwise raise CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute. If check_call() was unable to start the process it will propagate the exception that was raised.

需要捕獲 stdout 或 stderr 的代碼應(yīng)當(dāng)改用 run():

run(..., check=True)

要屏蔽 stdout 或 stderr,可提供 DEVNULL 這個(gè)值。

上面顯示的參數(shù)只是常見(jiàn)的一些。 完整的函數(shù)簽名與 Popen 構(gòu)造器的相同 —— 此函數(shù)會(huì)將所提供的 timeout 之外的全部參數(shù)直接傳遞給目標(biāo)接口。

備注

請(qǐng)不要在此函數(shù)中使用 stdout=PIPEstderr=PIPE。 如果子進(jìn)程向管道生成了足以填滿 OS 管理緩沖區(qū)的輸出而管道還未被讀取時(shí)它將會(huì)阻塞。

在 3.3 版更改: timeout 被添加

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

附帶參數(shù)運(yùn)行命令并返回其輸出。

如果返回碼非零則會(huì)引發(fā) CalledProcessError。 CalledProcessError 對(duì)象將在 returncode 屬性中保存返回碼并在 output 屬性中保存所有輸出。

這相當(dāng)于:

run(..., check=True, stdout=PIPE).stdout

上面顯示的參數(shù)只是常見(jiàn)的一些。 完整的函數(shù)簽名與 run() 的大致相同 —— 大部分參數(shù)會(huì)通過(guò)該接口直接傳遞。 存在一個(gè)與 run() 行為不同的 API 差異:傳遞 input=None 的行為將與 input=b'' (或 input='',具體取決于其他參數(shù)) 一樣而不是使用父對(duì)象的標(biāo)準(zhǔn)輸入文件處理。

默認(rèn)情況下,此函數(shù)將把數(shù)據(jù)返回為已編碼的字節(jié)串。 輸出數(shù)據(jù)的實(shí)際編碼格式將取決于發(fā)起調(diào)用的命令,因此解碼為文本的操作往往需要在應(yīng)用程序?qū)蛹?jí)上進(jìn)行處理。

此行為可以通過(guò)設(shè)置 text, encoding, errors 或?qū)?universal_newlines 設(shè)為 True 來(lái)重載,具體描述見(jiàn) 常用參數(shù)run()

要在結(jié)果中同時(shí)捕獲標(biāo)準(zhǔn)錯(cuò)誤,請(qǐng)使用 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 新版功能.

在 3.3 版更改: timeout 被添加

在 3.4 版更改: 增加了對(duì) input 關(guān)鍵字參數(shù)的支持。

在 3.6 版更改: 增加了 encodingerrors。 詳情參見(jiàn) run()

3.7 新版功能: text 作為 universal_newlines 的一個(gè)更具可讀性的別名被添加。

使用 subprocess 模塊替換舊函數(shù)?

在這一節(jié)中,"a 改為 b" 意味著 b 可以被用作 a 的替代。

備注

在這一節(jié)中的所有 "a" 函數(shù)會(huì)在找不到被執(zhí)行的程序時(shí)(差不多)靜默地失敗;"b" 替代函數(shù)則會(huì)改為引發(fā) OSError。

此外,在使用 check_output() 時(shí)如果替代函數(shù)所請(qǐng)求的操作產(chǎn)生了非零返回值則將失敗并引發(fā) CalledProcessError。 操作的輸出仍能以所引發(fā)異常的 output 屬性的方式被訪問(wèn)。

在下列例子中,我們假定相關(guān)的函數(shù)都已從 subprocess 模塊中導(dǎo)入了。

替代 /bin/sh shell 命令替換?

output=$(mycmd myarg)

改為:

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

替代 shell 管道?

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]

啟動(dòng) p2 之后再執(zhí)行 p1.stdout.close() 調(diào)用很重要,這是為了讓 p1 能在 p2 先于 p1 退出時(shí)接收到 SIGPIPE。

另外,對(duì)于受信任的輸入,shell 本身的管道支持仍然可被直接使用:

output=$(dmesg | grep hda)

改為:

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

替代 os.system()?

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

注釋?zhuān)?/p>

  • 通過(guò) shell 來(lái)調(diào)用程序通常是不必要的。

  • call() 返回值的編碼方式與 os.system() 的不同。

  • os.system() 函數(shù)在命令運(yùn)行期間會(huì)忽略 SIGINT 和 SIGQUIT 信號(hào),但調(diào)用方必須在使用 subprocess 模塊時(shí)分別執(zhí)行此操作。

一個(gè)更現(xiàn)實(shí)的例子如下所示:

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 函數(shù)族?

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"])

Vector 示例:

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

Environment 示例:

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)

返回碼以如下方式處理轉(zhuǎn)寫(xiě):

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")

來(lái)自 popen2 模塊的替代函數(shù)?

備注

如果 popen2 函數(shù)的 cmd 參數(shù)是一個(gè)字符串,命令會(huì)通過(guò) /bin/sh 來(lái)執(zhí)行。 如果是一個(gè)列表,命令會(huì)被直接執(zhí)行。

(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 基本上類(lèi)似于 subprocess.Popen,不同之處在于:

  • Popen 如果執(zhí)行失敗會(huì)引發(fā)一個(gè)異常。

  • capturestderr 參數(shù)被替換為 stderr 參數(shù)。

  • 必須指定 stdin=PIPEstdout=PIPE。

  • popen2 默認(rèn)會(huì)關(guān)閉所有文件描述符,但對(duì)于 Popen 你必須指明 close_fds=True 以才能在所有平臺(tái)或較舊的 Python 版本中確保此行為。

舊式的 Shell 發(fā)起函數(shù)?

此模塊還提供了以下來(lái)自 2.x commands 模塊的舊版函數(shù)。 這些操作會(huì)隱式地發(fā)起調(diào)用系統(tǒng) shell 并且上文所描述的有關(guān)安全與異常處理一致性保證都不適用于這些函數(shù)。

subprocess.getstatusoutput(cmd, *, encoding=None, errors=None)?

返回在 shell 中執(zhí)行 cmd 產(chǎn)生的 (exitcode, output)。

Execute the string cmd in a shell with Popen.check_output() and return a 2-tuple (exitcode, output). encoding and errors are used to decode output; see the notes on 常用參數(shù) for more details.

末尾的一個(gè)換行符會(huì)從輸出中被去除。 命令的退出碼可被解讀為子進(jìn)程的返回碼。 例如:

>>>
>>> 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 支持。

此函數(shù)現(xiàn)在返回 (exitcode, output) 而不是像 Python 3.3.3 及更早的版本那樣返回 (status, output)。 exitcode 的值與 returncode 相同。

3.11 新版功能: Added encoding and errors arguments.

subprocess.getoutput(cmd, *, encoding=None, errors=None)?

返回在 shell 中執(zhí)行 cmd 產(chǎn)生的輸出(stdout 和 stderr)。

類(lèi)似于 getstatusoutput(),但退出碼會(huì)被忽略并且返回值為包含命令輸出的字符串。 例如:

>>>
>>> subprocess.getoutput('ls /bin/ls')
'/bin/ls'

可用性: POSIX 和 Windows。

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

3.11 新版功能: Added encoding and errors arguments.

備注?

在 Windows 上將參數(shù)列表轉(zhuǎn)換為一個(gè)字符串?

在 Windows 上,args 序列會(huì)被轉(zhuǎn)換為可使用以下規(guī)則來(lái)解析的字符串(對(duì)應(yīng)于 MS C 運(yùn)行時(shí)所使用的規(guī)則):

  1. 參數(shù)以空白符分隔,即空格符或制表符。

  2. 用雙引號(hào)標(biāo)示的字符串會(huì)被解讀為單個(gè)參數(shù),而不再考慮其中的空白符。 一個(gè)參數(shù)可以嵌套用引號(hào)標(biāo)示的字符串。

  3. 帶有一個(gè)反斜杠前綴的雙引號(hào)會(huì)被解讀為雙引號(hào)字面值。

  4. 反斜杠會(huì)按字面值解讀,除非它是作為雙引號(hào)的前綴。

  5. 如果反斜杠被作為雙引號(hào)的前綴,則每個(gè)反斜杠對(duì)會(huì)被解讀為一個(gè)反斜杠字面值。 如果反斜杠數(shù)量為奇數(shù),則最后一個(gè)反斜杠會(huì)如規(guī)則 3 所描述的那樣轉(zhuǎn)義下一個(gè)雙引號(hào)。

參見(jiàn)

shlex

此模塊提供了用于解析和轉(zhuǎn)義命令行的函數(shù)。

Disabling use of vfork() or posix_spawn()?

On Linux, subprocess defaults to using the vfork() system call internally when it is safe to do so rather than fork(). This greatly improves performance.

If you ever encounter a presumed highly-unusual situation where you need to prevent vfork() from being used by Python, you can set the subprocess._USE_VFORK attribute to a false value.

subprocess._USE_VFORK = False # See CPython issue gh-NNNNNN.

Setting this has no impact on use of posix_spawn() which could use vfork() internally within its libc implementation. There is a similar subprocess._USE_POSIX_SPAWN attribute if you need to prevent use of that.

subprocess._USE_POSIX_SPAWN = False # See CPython issue gh-NNNNNN.

It is safe to set these to false on any Python version. They will have no effect on older versions when unsupported. Do not assume the attributes are available to read. Despite their names, a true value does not indicate that the corresponding function will be used, only that that it may be.

Please file issues any time you have to use these private knobs with a way to reproduce the issue you were seeing. Link to that issue from a comment in your code.

3.8 新版功能: _USE_POSIX_SPAWN

3.11 新版功能: _USE_VFORK