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 接口。
run() 函數(shù)是在 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)? 運(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, check 和 capture_output 除外)。如果 capture_output 設(shè)為 true,stdout 和 stderr 將會(huì)被捕獲。在使用時(shí),內(nèi)置的
Popen對(duì)象將自動(dòng)用stdout=PIPE和stderr=PIPE創(chuàng)建。stdout 和 stderr 參數(shù)不應(yīng)當(dāng)與 capture_output 同時(shí)提供。如果你希望捕獲并將兩個(gè)流合并在一起,使用stdout=PIPE和stderr=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é)序列。 如果指定了 encoding 或 errors 或者將 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ò)指定的 encoding 和 errors 以文本模式打開(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 版更改: 添加了 encoding 和 errors 形參.
在 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? 可被
Popen的 stdin, stdout 或者 stderr 參數(shù)使用的特殊值, 表示使用特殊文件os.devnull.3.3 新版功能.
-
subprocess.PIPE? 可被
Popen的 stdin, stdout 或者 stderr 參數(shù)使用的特殊值, 表示打開(kāi)標(biāo)準(zhǔn)流的管道. 常用于Popen.communicate().
-
subprocess.STDOUT? 可被
Popen的 stdin , 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。
3.3 新版功能.
在 3.5 版更改: 添加了 stdout 和 stderr 屬性。
-
-
exception
subprocess.CalledProcessError? SubprocessError的子類(lèi),當(dāng)一個(gè)被check_call()或check_output()函數(shù)運(yùn)行的子進(jìn)程返回了非零退出碼時(shí)被拋出。-
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。
在 3.5 版更改: 添加了 stdout 和 stderr 屬性。
-
常用參數(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 和 stderr 分別指定了執(zhí)行的程序的標(biāo)準(zhǔn)輸入、輸出和標(biāo)準(zhǔn)錯(cuò)誤文件句柄。合法的值有
PIPE、DEVNULL、 一個(gè)現(xiàn)存的文件描述符(一個(gè)正整數(shù))、一個(gè)現(xiàn)存的文件對(duì)象以及None。PIPE表示應(yīng)該新建一個(gè)對(duì)子進(jìn)程的管道。DEVNULL表示使用特殊的文件os.devnull。當(dāng)使用默認(rèn)設(shè)置None時(shí),將不會(huì)進(jìn)行重定向,子進(jìn)程的文件流將繼承自父進(jìn)程。另外, stderr 可能為STDOUT,表示來(lái)自于子進(jìn)程的標(biāo)準(zhǔn)錯(cuò)誤數(shù)據(jù)應(yīng)該被 stdout 相同的句柄捕獲。如果 encoding 或 errors 被指定,或者 text (也名為 universal_newlines)為真,則文件對(duì)象 stdin 、 stdout 與 stderr 將會(huì)使用在此次調(diào)用中指定的 encoding 和 errors 以文本模式打開(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ì)于 stdout 和 stderr, 所有輸出的換行符都被轉(zhuǎn)換為'\n'。更多信息,查看io.TextIOWrapper類(lèi)的文檔。如果文本模式未被使用, stdin, stdout 和 stderr 將會(huì)以二進(jìn)制流模式打開(kāi)。沒(méi)有編碼與換行符轉(zhuǎn)換發(fā)生。
3.6 新版功能: 添加了 encoding 和 errors 形參。
3.7 新版功能: 添加了 text 形參作為 universal_newlines 的別名。
注解
文件對(duì)象
Popen.stdin、Popen.stdout和Popen.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)到用戶家目錄,這將非常有用。但是,注意 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=(), *, encoding=None, errors=None, text=None)? 在一個(gè)新的進(jìn)程中執(zhí)行子程序。在 POSIX,此類(lèi)使用類(lèi)似于
os.execvp()的行為來(lái)執(zhí)行子程序。在 Windows,此類(lèi)使用了 WindowsCreateProcess()函數(shù)。Popen的參數(shù)如下:args 應(yīng)當(dāng)是一個(gè)程序的參數(shù)列表或者一個(gè)簡(jiǎn)單的字符串。默認(rèn)情況下,如果 args 是一個(gè)序列,將運(yùn)行的程序是此序列的第一項(xiàng)。如果 args 是一個(gè)字符串,解釋是平臺(tái)相關(guān)的,如下所述。有關(guān)默認(rèn)行為的其他差異,見(jiàn) shell 和 executable 參數(shù)。除非另有說(shuō)明,推薦將 args 作為序列傳遞。
向外部函數(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()只處理字符串。參數(shù) shell (默認(rèn)為
False)指定是否使用 shell 執(zhí)行程序。如果 shell 為True,更推薦將 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=True, executable 替換 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。stdin, stdout 和 stderr 分別指定被運(yùn)行的程序的標(biāo)準(zhǔn)輸入、輸出和標(biāo)準(zhǔn)錯(cuò)誤的文件句柄。合法的值有
PIPE,DEVNULL, 一個(gè)存在的文件描述符(一個(gè)正整數(shù)),一個(gè)存在的 文件對(duì)象 以及None。PIPE表示應(yīng)創(chuàng)建一個(gè)新的對(duì)子進(jìn)程的管道。DEVNULL表示使用特殊的os.devnull文件。使用默認(rèn)的None,則不進(jìn)行成定向;子進(jìn)程的文件流將繼承自父進(jìn)程。另外, stderr 可設(shè)為STDOUT,表示應(yīng)用程序的標(biāo)準(zhǔn)錯(cuò)誤數(shù)據(jù)應(yīng)和標(biāo)準(zhǔn)輸出一同捕獲。如果 preexec_fn 被設(shè)為一個(gè)可調(diào)用對(duì)象,此對(duì)象將在子進(jìn)程剛創(chuàng)建時(shí)被調(diào)用。(僅 POSIX)
警告
preexec_fn 形參在應(yīng)用程序中存在多線程時(shí)是不安全的。子進(jìn)程在調(diào)用前可能死鎖。如果你必須使用它,保持警惕!最小化你調(diào)用的庫(kù)的數(shù)量。
注解
如果你需要修改子進(jìn)程環(huán)境,使用 env 形參而非在 preexec_fn 中進(jìn)行。 start_new_session 形參可以代替之前常用的 preexec_fn 來(lái)在子進(jìn)程中調(diào)用 os.setsid()。
如果 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.IpAttributeList的handle_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?,F(xiàn)在重定向標(biāo)準(zhǔn)句柄時(shí)有可能設(shè)置 close_fds 為True。(標(biāo)準(zhǔn)句柄指三個(gè) stdio 的句柄)pass_fds 是一個(gè)可選的在父子進(jìn)程間保持打開(kāi)的文件描述符序列。提供任何 pass_fds 將強(qiáng)制 close_fds 為
True。(僅 POSIX)3.2 新版功能: 加入了 pass_fds 形參。
如果 cwd 不為
None,此函數(shù)在執(zhí)行子進(jìn)程前改變當(dāng)前工作目錄為 cwd。 cwd 可以為一個(gè)str和 path-like 對(duì)象。特別要注意,當(dāng)可執(zhí)行文件的路徑為相對(duì)路徑時(shí),此函數(shù)按相對(duì)于 cwd 的路徑來(lái)尋找 executable (或者 args 的第一項(xiàng))。在 3.6 版更改: cwd 形參接受一個(gè) path-like object。
?如果 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 被加入。
如果 start_new_session 為 true,則 setsid() 系統(tǒng)調(diào)用將在子進(jìn)程執(zhí)行之前被執(zhí)行。(僅 POSIX)
在 3.2 版更改: start_new_session 被添加。
如果 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。如果 encoding 或 errors 被指定,或者 text 為 true,則文件對(duì)象 stdin, stdout 和 stderr 將會(huì)以指定的編碼和 errors 以文本模式打開(kāi),如同 常用參數(shù) 所述。 universal_newlines 參數(shù)等同于 text 并且提供向后兼容性。默認(rèn)情況下,文件對(duì)象都以二進(jìn)制模式打開(kāi)。
3.6 新版功能: encoding 和 errors 被添加。
3.7 新版功能: text 作為 universal_newlines 的一個(gè)更具可讀性的別名被添加。
如果給出, startupinfo 將是一個(gè)將被傳遞給底層的
CreateProcess函數(shù)的STARTUPINFO對(duì)象。 creationflags,如果給出,可以是一個(gè)或多個(gè)以下標(biāo)志之一:Popen 對(duì)象支持通過(guò)
with語(yǔ)句作為上下文管理器,在退出時(shí)關(guān)閉文件描述符并等待進(jìn)程:with Popen(["ifconfig"], stdout=PIPE) as proc: log.write(proc.stdout.read())
在 3.2 版更改: 添加了上下文管理器支持。
在 3.6 版更改: 現(xiàn)在,如果 Popen 析構(gòu)時(shí)子進(jìn)程仍然在運(yùn)行,則析構(gòu)器會(huì)發(fā)送一個(gè)
ResourceWarning警告。
異常?
在子進(jìn)程中拋出的異常,在新的進(jìn)程開(kāi)始執(zhí)行前,將會(huì)被再次在父進(jìn)程中拋出。
最常見(jiàn)的被拋出異常是 OSError。例如,當(dāng)嘗試執(zhí)行一個(gè)不存在的文件時(shí)就會(huì)發(fā)生。應(yīng)用程序需要為 OSError 異常做好準(zhǔ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í)現(xiàn)絕不會(huì)隱式調(diào)用一個(gè)系統(tǒng) shell。這意味著任何字符,包括 shell 元字符,可以安全地被傳遞給子進(jìn)程。如果 shell 被明確地調(diào)用,通過(guò) shell=True 設(shè)置,則確保所有空白字符和元字符被恰當(dāng)?shù)匕谝?hào)內(nèi)以避免 shell 注入 漏洞就由應(yīng)用程序負(fù)責(zé)了。
當(dāng)使用 shell=True, shlex.quote() 函數(shù)可以作為在將被用于構(gòu)造 shell 指令的字符串中轉(zhuǎn)義空白字符以及 shell 元字符的方案。
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)程交互:向 stdin 傳輸數(shù)據(jù)。從 stdout 和 stderr 讀取數(shù)據(jù),直到文件結(jié)束符。等待進(jìn)程終止??蛇x的 input 參數(shù)應(yīng)當(dāng)未被傳輸給子進(jìn)程的數(shù)據(jù),如果沒(méi)有數(shù)據(jù)應(yīng)被傳輸給子進(jìn)程則為
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)程。
注解
在 Windows, SIGTERM 是一個(gè)
terminate()的別名。 CTRL_C_EVENT 和 CTRL_BREAK_EVENT 可以被發(fā)送給以包含CREATE_NEW_PROCESS的 creationflags 形參啟動(dòng)的進(jìn)程。
-
Popen.terminate()? 停止下級(jí)進(jìn)程。 在 POSIX 操作系統(tǒng)上,此方法會(huì)發(fā)送 SIGTERM 給下級(jí)進(jìn)程。 在 Windows 上則會(huì)調(diào)用 Win32 API 函數(shù)
TerminateProcess()來(lái)停止下級(jí)進(jìn)程。
-
Popen.kill()? 殺死子進(jìn)程。 在 POSIX 操作系統(tǒng)上,此函數(shù)會(huì)發(fā)送 SIGKILL 給子進(jìn)程。 在 Windows 上
kill()則是terminate()的別名。
以下屬性也是可用的:
-
Popen.stdin? 如果 stdin 參數(shù)為
PIPE,此屬性是一個(gè)類(lèi)似open()返回的可寫(xiě)的流對(duì)象。如果 encoding 或 errors 參數(shù)被指定或者 universal_newlines 參數(shù)為True,則此流是一個(gè)文本流,否則是字節(jié)流。如果 stdin 參數(shù)非PIPE, 此屬性為None。
-
Popen.stdout? 如果 stdout 參數(shù)是
PIPE,此屬性是一個(gè)類(lèi)似open()返回的可讀流。從流中讀取子進(jìn)程提供的輸出。如果 encoding 或 errors 參數(shù)被指定或者 universal_newlines 參數(shù)為True,此流為文本流,否則為字節(jié)流。如果 stdout 參數(shù)非PIPE,此屬性為None。
-
Popen.stderr? 如果 stderr 參數(shù)是
PIPE,此屬性是一個(gè)類(lèi)似open()返回的可讀流。從流中讀取子進(jìn)程提供的輸出。如果 encoding 或 errors 參數(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)的屬性僅能通過(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。如此之外,此屬性被忽略。
-
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 errorERROR_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.hStdOutput和STARTUPINFO.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? Popencreationflags形參用于指明將創(chuàng)建一個(gè)新的進(jìn)程組。 這個(gè)旗標(biāo)對(duì)于在子進(jìn)程上使用os.kill()來(lái)說(shuō)是必須的。如果指定了
CREATE_NEW_CONSOLE則這個(gè)旗標(biāo)會(huì)被忽略。
-
subprocess.ABOVE_NORMAL_PRIORITY_CLASS? Popencreationflags形參用于指明一個(gè)新進(jìn)程將具有上述的平均優(yōu)先級(jí)。3.7 新版功能.
-
subprocess.BELOW_NORMAL_PRIORITY_CLASS? Popencreationflags形參用于指明一個(gè)新進(jìn)程將具有低于平均的優(yōu)先級(jí)。3.7 新版功能.
-
subprocess.HIGH_PRIORITY_CLASS? 用于指明一個(gè)新進(jìn)程將具有高優(yōu)先級(jí)的
Popencreationflags形參。3.7 新版功能.
-
subprocess.IDLE_PRIORITY_CLASS? 用于指明一個(gè)新進(jìn)程將具有空閑(最低)優(yōu)先級(jí)的
Popencreationflags形參。3.7 新版功能.
-
subprocess.NORMAL_PRIORITY_CLASS? 用于指明一個(gè)新進(jìn)程將具有正常(默認(rèn))優(yōu)先級(jí)的
Popencreationflags形參。3.7 新版功能.
-
subprocess.REALTIME_PRIORITY_CLASS? 用于指明一個(gè)新進(jìn)程將具有實(shí)時(shí)優(yōu)先級(jí)的
Popencreationflags形參。 你應(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)建窗口的
Popencreationflags形參。3.7 新版功能.
-
subprocess.DETACHED_PROCESS? 指明一個(gè)新進(jìn)程將不會(huì)繼承其父控制臺(tái)的
Popencreationflags形參。 這個(gè)值不能與 CREATE_NEW_CONSOLE 一同使用。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屬性。Code needing to capture stdout or stderr should use
run()instead:run(...).returncode
要屏蔽 stdout 或 stderr,可提供
DEVNULL這個(gè)值。上面顯示的參數(shù)只是常見(jiàn)的一些。 完整的函數(shù)簽名與
Popen構(gòu)造器的相同 —— 此函數(shù)會(huì)將所提供的 timeout 之外的全部參數(shù)直接傳遞給目標(biāo)接口。注解
請(qǐng)不要在此函數(shù)中使用
stdout=PIPE或stderr=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)? 附帶參數(shù)運(yùn)行命令。 等待命令完成。 如果返回碼為零則正常返回,否則引發(fā)
CalledProcessError。CalledProcessError對(duì)象將在returncode屬性中保存返回碼。Code needing to capture stdout or stderr should use
run()instead:run(..., check=True)
要屏蔽 stdout 或 stderr,可提供
DEVNULL這個(gè)值。上面顯示的參數(shù)只是常見(jiàn)的一些。 完整的函數(shù)簽名與
Popen構(gòu)造器的相同 —— 此函數(shù)會(huì)將所提供的 timeout 之外的全部參數(shù)直接傳遞給目標(biāo)接口。注解
請(qǐng)不要在此函數(shù)中使用
stdout=PIPE或stderr=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ì)被直接傳遞給目標(biāo)接口。 但是,顯式地傳遞input=None來(lái)繼承父對(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 版更改: 增加了 encoding 和 errors。 詳情參見(jiàn)
run()。3.7 新版功能: text 作為 universal_newlines 的一個(gè)更具可讀性的別名被添加。
使用 subprocess 模塊替換舊函數(shù)?
在這一節(jié)中,"a 改為 b" 意味著 b 可以被用作 a 的替代。
注解
在這一節(jié)中的所有 "a" 函數(shù)會(huì)在找不到被執(zhí)行的程序時(shí)(差不多)靜默地失??;"b" 替代則會(huì)改為引發(fā) OSError。
此外,在使用 check_output() 時(shí)如果替代函數(shù)所請(qǐng)求的操作產(chǎn)生了非零返回值則將失敗并引發(fā) CalledProcessError。 操作的輸出仍能以所引發(fā)異常的 output 屬性的方式被訪問(wèn)。
在下列例子中,我們假定相關(guān)的函數(shù)都已從 subprocess 模塊中導(dǎo)入了。
Replacing /bin/sh shell backquote?
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]
The p1.stdout.close() call after starting the p2 is important in order for p1 to receive a SIGPIPE if p2 exits before p1.
另外,對(duì)于受信任的輸入,shell 本身的管道支持仍然可被直接使用:
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)
注釋:
通過(guò) shell 來(lái)調(diào)用程序通常是不必要的。
一個(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.Popen3 和 popen2.Popen4 基本上類(lèi)似于 subprocess.Popen,不同之處在于:
舊式的 Shell 發(fā)起函數(shù)?
此模塊還提供了以下來(lái)自 2.x commands 模塊的舊版函數(shù)。 這些操作會(huì)隱式地發(fā)起調(diào)用系統(tǒng) shell 并且上文所描述的有關(guān)安全與異常處理一致性保證都不適用于這些函數(shù)。
-
subprocess.getstatusoutput(cmd)? 返回在 shell 中執(zhí)行 cmd 產(chǎn)生的
(exitcode, output)。在 shell 中以
Popen.check_output()執(zhí)行字符串 cmd 并返回一個(gè) 2 元組(exitcode, output)。 會(huì)使用當(dāng)前區(qū)域設(shè)置的編碼格式;請(qǐng)參閱 常用參數(shù) 中的說(shuō)明來(lái)了解詳情。末尾的一個(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相同。
-
subprocess.getoutput(cmd)? 返回在 shell 中執(zhí)行 cmd 產(chǎn)生的輸出(stdout 和 stderr)。
類(lèi)似于
getstatusoutput(),但退出碼會(huì)被忽略并且返回值為包含命令輸出的字符串。 例如:>>> subprocess.getoutput('ls /bin/ls') '/bin/ls'
可用性: POSIX 和 Windows。
在 3.3.4 版更改: 添加了 Windows 支持
注釋?
在 Windows 上將參數(shù)列表轉(zhuǎn)換為一個(gè)字符串?
在 Windows 上,args 序列會(huì)被轉(zhuǎn)換為可使用以下規(guī)則來(lái)解析的字符串(對(duì)應(yīng)于 MS C 運(yùn)行時(shí)所使用的規(guī)則):
參數(shù)以空白符分隔,即空格符或制表符。
用雙引號(hào)標(biāo)示的字符串會(huì)被解讀為單個(gè)參數(shù),而不再考慮其中的空白符。 一個(gè)參數(shù)可以嵌套用引號(hào)標(biāo)示的字符串。
帶有一個(gè)反斜杠前綴的雙引號(hào)會(huì)被解讀為雙引號(hào)字面值。
反斜杠會(huì)按字面值解讀,除非它是作為雙引號(hào)的前綴。
如果反斜杠被作為雙引號(hào)的前綴,則每個(gè)反斜杠對(duì)會(huì)被解讀為一個(gè)反斜杠字面值。 如果反斜杠數(shù)量為奇數(shù),則最后一個(gè)反斜杠會(huì)如規(guī)則 3 所描述的那樣轉(zhuǎn)義下一個(gè)雙引號(hào)。
參見(jiàn)
shlex此模塊提供了用于解析和轉(zhuǎn)義命令行的函數(shù)。
