subprocess
--- 子進(jìn)程管理?
源代碼: Lib/subprocess.py
subprocess
模塊允許你生成新的進(jìn)程,連接它們的輸入、輸出、錯誤管道,并且獲取它們的返回碼。此模塊打算代替一些老舊的模塊與功能:
os.system
os.spawn*
在下面的段落中,你可以找到關(guān)于 subprocess
模塊如何代替這些模塊和功能的相關(guān)信息。
參見
PEP 324 -- 提出 subprocess 模塊的 PEP
使用 subprocess
模塊?
推薦的調(diào)用子進(jìn)程的方式是在任何它支持的用例中使用 run()
函數(shù)。對于更進(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)?
運行被 arg 描述的指令. 等待指令完成, 然后返回一個
CompletedProcess
實例.以上顯示的參數(shù)僅僅是最簡單的一些,下面 常用參數(shù) 描述(因此在縮寫簽名中使用僅關(guān)鍵字標(biāo)示)。完整的函數(shù)頭和
Popen
的構(gòu)造函數(shù)一樣,此函數(shù)接受的大多數(shù)參數(shù)都被傳遞給該接口。(timeout, input, check 和 capture_output 除外)。如果 capture_output 設(shè)為 true,stdout 和 stderr 將會被捕獲。在使用時,內(nèi)置的
Popen
對象將自動用stdout=PIPE
和stderr=PIPE
創(chuàng)建。stdout 和 stderr 參數(shù)不應(yīng)當(dāng)與 capture_output 同時提供。如果你希望捕獲并將兩個流合并在一起,使用stdout=PIPE
和stderr=STDOUT
來代替 capture_output。timeout 參數(shù)將被傳遞給
Popen.communicate()
。如果發(fā)生超時,子進(jìn)程將被殺死并等待。TimeoutExpired
異常將在子進(jìn)程中斷后被拋出。input 參數(shù)將被傳遞給
Popen.communicate()
以及子進(jìn)程的 stdin。 如果使用此參數(shù),它必須是一個字節(jié)序列。 如果指定了 encoding 或 errors 或者將 text 設(shè)置為True
,那么也可以是一個字符串。 當(dāng)使用此參數(shù)時,在創(chuàng)建內(nèi)部Popen
對象時將自動帶上stdin=PIPE
,并且不能再手動指定 stdin 參數(shù)。如果 check 設(shè)為 True, 并且進(jìn)程以非零狀態(tài)碼退出, 一個
CalledProcessError
異常將被拋出. 這個異常的屬性將設(shè)置為參數(shù), 退出碼, 以及標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯誤, 如果被捕獲到.如果 encoding 或者 error 被指定, 或者 text 被設(shè)為 True, 標(biāo)準(zhǔn)輸入, 標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯誤的文件對象將通過指定的 encoding 和 errors 以文本模式打開, 否則以默認(rèn)的
io.TextIOWrapper
打開. universal_newline 參數(shù)等同于 text 并且提供了向后兼容性. 默認(rèn)情況下, 文件對象是以二進(jìn)制模式打開的.如果 env 不是
None
, 它必須是一個字典, 為新的進(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 的一個更好理解的別名. 添加了 capture_output 形參.
- class subprocess.CompletedProcess?
run()
的返回值, 代表一個進(jìn)程已經(jīng)結(jié)束.- args?
被用作啟動進(jìn)程的參數(shù). 可能是一個列表或字符串.
- returncode?
子進(jìn)程的退出狀態(tài)碼. 通常來說, 一個為 0 的退出碼表示進(jìn)程運行正常.
一個負(fù)值
-N
表示子進(jìn)程被信號N
中斷 (僅 POSIX).
- stdout?
從子進(jìn)程捕獲到的標(biāo)準(zhǔn)輸出. 一個字節(jié)序列, 或一個字符串, 如果
run()
是設(shè)置了 encoding, errors 或者text=True
來運行的. 如果未有捕獲, 則為None
.如果你通過
stderr=subprocess.STDOUT
運行進(jìn)程,標(biāo)準(zhǔn)輸入和標(biāo)準(zhǔn)錯誤將被組合在這個屬性中,并且stderr
將為None
。
- stderr?
捕獲到的子進(jìn)程的標(biāo)準(zhǔn)錯誤. 一個字節(jié)序列, 或者一個字符串, 如果
run()
是設(shè)置了參數(shù) encoding, errors 或者text=True
運行的. 如果未有捕獲, 則為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ù)使用的特殊值, 表示打開標(biāo)準(zhǔn)流的管道. 常用于Popen.communicate()
.
- subprocess.STDOUT?
可被
Popen
的 stdin , stdout 或者 stderr 參數(shù)使用的特殊值, 表示標(biāo)準(zhǔn)錯誤與標(biāo)準(zhǔn)輸出使用同一句柄。
- exception subprocess.SubprocessError?
此模塊的其他異常的基類。
3.3 新版功能.
- exception subprocess.TimeoutExpired?
SubprocessError
的子類,等待子進(jìn)程的過程中發(fā)生超時時被拋出。- cmd?
用于創(chuàng)建子進(jìn)程的指令。
- timeout?
超時秒數(shù)。
- output?
子進(jìn)程的輸出, 如果被
run()
或check_output()
捕獲。否則為None
。
3.3 新版功能.
在 3.5 版更改: 添加了 stdout 和 stderr 屬性。
- exception subprocess.CalledProcessError?
Subclass of
SubprocessError
, raised when a process run bycheck_call()
,check_output()
, orrun()
(withcheck=True
) returns a non-zero exit status.- returncode?
子進(jìn)程的退出狀態(tài)。如果程序由一個信號終止,這將會被設(shè)為一個負(fù)的信號碼。
- cmd?
用于創(chuàng)建子進(jìn)程的指令。
- output?
子進(jìn)程的輸出, 如果被
run()
或check_output()
捕獲。否則為None
。
在 3.5 版更改: 添加了 stdout 和 stderr 屬性。
常用參數(shù)?
為了支持豐富的使用案例, Popen
的構(gòu)造函數(shù)(以及方便的函數(shù))接受大量可選的參數(shù)。對于大多數(shù)典型的用例,許多參數(shù)可以被安全地留以它們的默認(rèn)值。通常需要的參數(shù)有:
args 被所有調(diào)用需要,應(yīng)當(dāng)為一個字符串,或者一個程序參數(shù)序列。提供一個參數(shù)序列通常更好,它可以更小心地使用參數(shù)中的轉(zhuǎn)義字符以及引用(例如允許文件名中的空格)。如果傳遞一個簡單的字符串,則 shell 參數(shù)必須為
True
(見下文)或者該字符串中將被運行的程序名必須用簡單的命名而不指定任何參數(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, andNone
.PIPE
indicates that a new pipe to the child should be created.DEVNULL
indicates that the special fileos.devnull
will be used. With the default settings ofNone
, no redirection will occur; the child's file handles will be inherited from the parent. Additionally, stderr can beSTDOUT
, which indicates that the stderr data from the child process should be captured into the same file handle as for stdout.如果 encoding 或 errors 被指定,或者 text (也名為 universal_newlines)為真,則文件對象 stdin 、 stdout 與 stderr 將會使用在此次調(diào)用中指定的 encoding 和 errors 以文本模式打開或者為默認(rèn)的
io.TextIOWrapper
。當(dāng)構(gòu)造函數(shù)的 newline 參數(shù)為
None
時。對于 stdin, 輸入的換行符'\n'
將被轉(zhuǎn)換為默認(rèn)的換行符os.linesep
。對于 stdout 和 stderr, 所有輸出的換行符都被轉(zhuǎn)換為'\n'
。更多信息,查看io.TextIOWrapper
類的文檔。如果文本模式未被使用, stdin, stdout 和 stderr 將會以二進(jìn)制流模式打開。沒有編碼與換行符轉(zhuǎn)換發(fā)生。
3.6 新版功能: 添加了 encoding 和 errors 形參。
3.7 新版功能: 添加了 text 形參作為 universal_newlines 的別名。
備注
文件對象
Popen.stdin
、Popen.stdout
和Popen.stderr
的換行符屬性不會被Popen.communicate()
方法更新。如果 shell 設(shè)為
True
,,則使用 shell 執(zhí)行指定的指令。如果您主要使用 Python 增強的控制流(它比大多數(shù)系統(tǒng) shell 提供的強大),并且仍然希望方便地使用其他 shell 功能,如 shell 管道、文件通配符、環(huán)境變量展開以及~
展開到用戶家目錄,這將非常有用。但是,注意 Python 自己也實現(xiàn)了許多類似 shell 的特性(例如glob
,fnmatch
,os.walk()
,os.path.expandvars()
,os.path.expanduser()
和shutil
)。在 3.3 版更改: 當(dāng) universal_newline 被設(shè)為
True
,則類使用locale.getpreferredencoding(False)
編碼來代替locale.getpreferredencoding()
。關(guān)于它們的區(qū)別的更多信息,見io.TextIOWrapper
。備注
在使用
shell=True
之前, 請閱讀 Security Considerations 段落。
這些選項以及所有其他選項在 Popen
構(gòu)造函數(shù)文檔中有更詳細(xì)的描述。
Popen 構(gòu)造函數(shù)?
此模塊的底層的進(jìn)程創(chuàng)建與管理由 Popen
類處理。它提供了很大的靈活性,因此開發(fā)者能夠處理未被便利函數(shù)覆蓋的不常見用例。
- 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)?
在一個新的進(jìn)程中執(zhí)行子程序。 在 POSIX 上,該類會使用類似于
os.execvpe()
的行為來執(zhí)行子程序。 在 Windows 上,該類會使用 WindowsCreateProcess()
函數(shù)。Popen
的參數(shù)如下。args 應(yīng)當(dāng)是一個程序參數(shù)的序列或者是一個單獨的字符串或 path-like object。 默認(rèn)情況下,如果 args 是序列則要運行的程序為 args 中的第一項。 如果 args 是字符串,則其解讀依賴于具體平臺,如下所述。 請查看 shell 和 executable 參數(shù)了解其與默認(rèn)行為的其他差異。 除非另有說明,否則推薦以序列形式傳入 args。
警告
為了最大化可靠性,請使用可執(zhí)行文件的完整限定路徑。 要在
PATH
中搜索一個未限定名稱,請使用shutil.which()
。 在所有平臺上,傳入sys.executable
是再次啟動當(dāng)前 Python 解釋器的推薦方式,并請使用-m
命令行格式來啟動已安裝的模塊。對 executable (或 args 的第一項) 路徑的解析方式依賴于具體平臺。 對于 POSIX,請參閱
os.execvpe()
,并要注意當(dāng)解析或搜索可執(zhí)行文件路徑時,cwd 會覆蓋當(dāng)前工作目錄而 env 可以覆蓋PATH
環(huán)境變量。 對于 Windows,請參閱lpApplicationName
的文檔以及lpCommandLine
形參 (傳給 WinAPICreateProcess
),并要注意當(dāng)解析或搜索可執(zhí)行文件路徑時如果傳入shell=False
,則 cwd 不會覆蓋當(dāng)前工作目錄而 env 無法覆蓋PATH
環(huán)境變量。 使用完整路徑可避免所有這些變化情況。向外部函數(shù)傳入序列形式參數(shù)的一個例子如下:
Popen(["/usr/bin/git", "commit", "-m", "Fixes a bug."])
在 POSIX,如果 args 是一個字符串,此字符串被作為將被執(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 中的空格分隔的選項(例如 -input)和參數(shù)(例如 eggs.txt )位于分開的列表元素中,而在需要時使用引號或反斜杠轉(zhuǎn)義的參數(shù)在 shell (例如包含空格的文件名或上面顯示的 echo 命令)是單獨的列表元素。
在 Windows,如果 args 是一個序列,他將通過一個在 在 Windows 上將參數(shù)列表轉(zhuǎn)換為一個字符串 描述的方式被轉(zhuǎn)換為一個字符串。這是因為底層的
CreateProcess()
只處理字符串。在 3.6 版更改: 在 POSIX 上如果 shell 為
False
并且序列包含路徑類對象則 args 形參可以接受一個 path-like object。在 3.8 版更改: 如果在Windows 上 shell 為
False
并且序列包含字節(jié)串和路徑類對象則 args 形參可以接受一個 path-like object。參數(shù) shell (默認(rèn)為
False
)指定是否使用 shell 執(zhí)行程序。如果 shell 為True
,更推薦將 args 作為字符串傳遞而非序列。在 POSIX,當(dāng)
shell=True
, shell 默認(rèn)為/bin/sh
。如果 args 是一個字符串,此字符串指定將通過 shell 執(zhí)行的命令。這意味著字符串的格式必須和在命令提示符中所輸入的完全相同。這包括,例如,引號和反斜杠轉(zhuǎn)義包含空格的文件名。如果 args 是一個序列,第一項指定了命令,另外的項目將作為傳遞給 shell (而非命令) 的參數(shù)對待。也就是說,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)。在運行一個批處理文件或者基于控制臺的可執(zhí)行文件時,不需要shell=True
。備注
在使用
shell=True
之前, 請閱讀 Security Considerations 段落。bufsize 將在
open()
函數(shù)創(chuàng)建了 stdin/stdout/stderr 管道文件對象時作為對應(yīng)的參數(shù)供應(yīng):0
表示不使用緩沖區(qū) (讀取與寫入是一個系統(tǒng)調(diào)用并且可以返回短內(nèi)容)1
表示行緩沖(只有universal_newlines=True
時才有用,例如,在文本模式中)任何其他正值表示使用一個約為對應(yīng)大小的緩沖區(qū)
負(fù)的 bufsize (默認(rèn))表示使用系統(tǒng)默認(rèn)的 io.DEFAULT_BUFFER_SIZE。
在 3.3.1 版更改: bufsize 現(xiàn)在默認(rèn)為 -1 來啟用緩沖,以符合大多數(shù)代碼所期望的行為。在 Python 3.2.4 和 3.3.1 之前的版本中,它錯誤地將默認(rèn)值設(shè)為了為
0
,這是無緩沖的并且允許短讀取。這是無意的,并且與大多數(shù)代碼所期望的 Python 2 的行為不一致。executable 參數(shù)指定一個要執(zhí)行的替換程序。這很少需要。當(dāng)
shell=True
, executable 替換 args 指定運行的程序。但是,原始的 args 仍然被傳遞給程序。大多數(shù)程序?qū)⒈?args 指定的程序作為命令名對待,這可以與實際運行的程序不同。在 POSIX, args 名作為實際調(diào)用程序中可執(zhí)行文件的顯示名稱,例如 ps。如果shell=True
,在 POSIX, executable 參數(shù)指定用于替換默認(rèn) shell/bin/sh
的 shell。在 3.6 版更改: 在POSIX 上 executable 形參可以接受一個 path-like object。
在 3.8 版更改: 在Windows 上 executable 形參可以接受一個字節(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, andNone
.PIPE
indicates that a new pipe to the child should be created.DEVNULL
indicates that the special fileos.devnull
will be used. With the default settings ofNone
, no redirection will occur; the child's file handles will be inherited from the parent. Additionally, stderr can beSTDOUT
, which indicates that the stderr data from the applications should be captured into the same file handle as for stdout.如果 preexec_fn 被設(shè)為一個可調(diào)用對象,此對象將在子進(jìn)程剛創(chuàng)建時被調(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()
oros.setpgid()
in the child.在 3.8 版更改: preexec_fn 形參在子解釋器中已不再受支持。 在子解釋器中使用此形參將引發(fā)
RuntimeError
。 這個新限制可能會影響部署在 mod_wsgi, uWSGI 和其他嵌入式環(huán)境中的應(yīng)用。如果 close_fds 為真,所有文件描述符除了
0
,1
,2
之外都會在子進(jìn)程執(zhí)行前關(guān)閉。而當(dāng) close_fds 為假時,文件描述符遵守它們繼承的標(biāo)志,如 文件描述符的繼承 所述。在 Windows,如果 close_fds 為真, 則子進(jìn)程不會繼承任何句柄,除非在
STARTUPINFO.IpAttributeList
的handle_list
的鍵中顯式傳遞,或者通過標(biāo)準(zhǔn)句柄重定向傳遞。在 3.2 版更改: close_fds 的默認(rèn)值已經(jīng)從
False
修改為上述值。在 3.7 版更改: 在 Windows,當(dāng)重定向標(biāo)準(zhǔn)句柄時 close_fds 的默認(rèn)值從
False
變?yōu)?True
。現(xiàn)在重定向標(biāo)準(zhǔn)句柄時有可能設(shè)置 close_fds 為True
。(標(biāo)準(zhǔn)句柄指三個 stdio 的句柄)pass_fds 是一個可選的在父子進(jìn)程間保持打開的文件描述符序列。提供任何 pass_fds 將強制 close_fds 為
True
。(僅 POSIX)在 3.2 版更改: 加入了 pass_fds 形參。
如果 cwd 不為
None
,此函數(shù)在執(zhí)行子進(jìn)程前會將當(dāng)前工作目錄改為 cwd。 cwd 可以是一個字符串、字節(jié)串或 路徑類對象。 在 POSIX 上,如果可執(zhí)行文件路徑為相對路徑則此函數(shù)會相對于 cwd 來查找 executable (或 args 的第一項)。在 3.6 版更改: 在 POSIX 上 cwd 形參接受一個 path-like object。
在 3.7 版更改: 在 Windows 上 cwd 形參接受一個 path-like object。
在 3.8 版更改: 在 Windows 上 cwd 形參接受一個字節(jié)串對象。
如果 restore_signals 為 true(默認(rèn)值),則 Python 設(shè)置為 SIG_IGN 的所有信號將在 exec 之前的子進(jìn)程中恢復(fù)為 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() 系統(tǒng)調(diào)用將于子進(jìn)程執(zhí)行之前在下級進(jìn)程中進(jìn)行。 如果所提供的值為一個字符串,將通過grp.getgrnam()
來查找它,并將使用gr_gid
中的值。 如果該值為一個整數(shù),它將被原樣傳遞。 (POSIX 專屬)可用性: POSIX
3.9 新版功能.
如果 extra_groups 不為
None
,則 setgroups() 系統(tǒng)調(diào)用將于子進(jìn)程之前在下級進(jìn)程中進(jìn)行。 在 extra_groups 中提供的字符串將通過grp.getgrnam()
來查找,并將使用gr_gid
中的值。 整數(shù)值將被原樣傳遞。 (POSIX 專屬)可用性: POSIX
3.9 新版功能.
如果 user 不為
None
,則 setreuid() 系統(tǒng)調(diào)用將于子進(jìn)程執(zhí)行之前在下級進(jìn)程中進(jìn)行。 如果所提供的值為一個字符串,將通過pwd.getpwnam()
來查找它,并將使用pw_uid
中的值。 如果該值為一個整數(shù),它將被原樣傳遞。 (POSIX 專屬)可用性: POSIX
3.9 新版功能.
如果 umask 不為負(fù)值,則 umask() 系統(tǒng)調(diào)用將在子進(jìn)程執(zhí)行之前在下級進(jìn)程中進(jìn)行。
可用性: POSIX
3.9 新版功能.
如果 env 不為
None
,則必須為一個為新進(jìn)程定義了環(huán)境變量的字典;這些用于替換繼承的當(dāng)前進(jìn)程環(huán)境的默認(rèn)行為。備注
如果指定, env 必須提供所有被子進(jìn)程需求的變量。在 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 常用參數(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 新版功能: encoding 和 errors 被添加。
3.7 新版功能: text 作為 universal_newlines 的一個更具可讀性的別名被添加。
如果給出, startupinfo 將是一個將被傳遞給底層的
CreateProcess
函數(shù)的STARTUPINFO
對象。 creationflags,如果給出,可以是一個或多個以下標(biāo)志之一:當(dāng)
PIPE
被用作 stdin, stdout 或 stderr 時 pipesize 可被用于改變管道的大小。 管道的大小僅會在受支持的平臺上被改變(當(dāng)撰寫本文檔時只有 Linux 支持)。 其他平臺將忽略此形參。3.10 新版功能: 增加了
pipesize
形參。Popen 對象支持通過
with
語句作為上下文管理器,在退出時關(guān)閉文件描述符并等待進(jìn)程:with Popen(["ifconfig"], stdout=PIPE) as proc: log.write(proc.stdout.read())
引發(fā)一個 審計事件
subprocess.Popen
,附帶參數(shù)executable
,args
,cwd
,env
。在 3.2 版更改: 添加了上下文管理器支持。
在 3.6 版更改: 現(xiàn)在,如果 Popen 析構(gòu)時子進(jìn)程仍然在運行,則析構(gòu)器會發(fā)送一個
ResourceWarning
警告。在 3.8 版更改: 在某些情況下 Popen 可以使用
os.posix_spawn()
以獲得更好的性能。在適用于 Linux 的 Windows 子系統(tǒng)和 QEMU 用戶模擬器上,使用os.posix_spawn()
的 Popen 構(gòu)造器不再會因找不到程序等錯誤而引發(fā)異常,而是上下級進(jìn)程失敗并返回一個非零的returncode
。
異常?
在子進(jìn)程中拋出的異常,在新的進(jìn)程開始執(zhí)行前,將會被再次在父進(jìn)程中拋出。
被引發(fā)的最一般異常是 OSError
。 例如這會在嘗試執(zhí)行一個不存在的文件時發(fā)生。 應(yīng)用程序應(yīng)當(dāng)為 OSError
異常做好準(zhǔn)備。 請注意,如果 shell=True
,則 OSError
僅會在未找到選定的 shell 本身時被引發(fā)。 要確定 shell 是否未找到所請求的應(yīng)用程序,必須檢查來自子進(jìn)程的返回碼或輸出。
如果 Popen
調(diào)用時有無效的參數(shù),則一個 ValueError
將被拋出。
check_call()
與 check_output()
在調(diào)用的進(jìn)程返回非零退出碼時將拋出 CalledProcessError
。
所有接受 timeout 形參的函數(shù)與方法,例如 call()
和 Popen.communicate()
將會在進(jìn)程退出前超時到期時拋出 TimeoutExpired
。
此模塊中定義的異常都繼承自 SubprocessError
。
3.3 新版功能: 基類
SubprocessError
被添加。
安全考量?
不同于某些其他的 popen 函數(shù),這個實現(xiàn)絕不會隱式地調(diào)用系統(tǒng) shell。 這意味著所有字符,包括 shell 元字符,都可以安全地被傳遞給子進(jìn)程。 如果 shell 通過 shell=True
被顯式地發(fā)起調(diào)用,則應(yīng)用程序有責(zé)任確保所有空白符和元字符被適當(dāng)?shù)剞D(zhuǎn)義以避免 shell 注入 漏洞。 在 某些平臺 上,可以使用 shlex.quote()
來執(zhí)行這樣的轉(zhuǎn)義。
Popen 對象?
Popen
類的實例擁有以下方法:
- Popen.poll()?
檢查子進(jìn)程是否已被終止。設(shè)置并返回
returncode
屬性。否則返回None
。
- Popen.wait(timeout=None)?
等待子進(jìn)程被終止。設(shè)置并返回
returncode
屬性。如果進(jìn)程在 timeout 秒后未中斷,拋出一個
TimeoutExpired
異常,可以安全地捕獲此異常并重新等待。備注
當(dāng)
stdout=PIPE
或者stderr=PIPE
并且子進(jìn)程產(chǎn)生了足以阻塞 OS 管道緩沖區(qū)接收更多數(shù)據(jù)的輸出到管道時,將會發(fā)生死鎖。當(dāng)使用管道時用Popen.communicate()
來規(guī)避它。備注
此函數(shù)使用了一個 busy loop (非阻塞調(diào)用以及短睡眠) 實現(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ìn)程的數(shù)據(jù),或者如果沒有要發(fā)送到下級進(jìn)程的數(shù)據(jù)則為None
。 如果流是以文本模式打開的,則 input 必須為字符串。 在其他情況下,它必須為字節(jié)串。communicate()
返回一個(stdout_data, stderr_data)
元組。如果文件以文本模式打開則為字符串;否則字節(jié)。注意如果你想要向進(jìn)程的 stdin 傳輸數(shù)據(jù),你需要通過
stdin=PIPE
創(chuàng)建此 Popen 對象。類似的,要從結(jié)果元組獲取任何非None
值,你同樣需要設(shè)置stdout=PIPE
或者stderr=PIPE
。如果進(jìn)程在 timeout 秒后未終止,一個
TimeoutExpired
異常將被拋出。捕獲此異常并重新等待將不會丟失任何輸出。如果超時到期,子進(jìn)程不會被殺死,所以為了正確清理一個行為良好的應(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ù)尺寸過大或無限,不要使用此方法。
在 3.3 版更改: timeout 被添加
- Popen.send_signal(signal)?
將信號 signal 發(fā)送給子進(jìn)程。
如果進(jìn)程已完成則不做任何操作。
備注
在 Windows, SIGTERM 是一個
terminate()
的別名。 CTRL_C_EVENT 和 CTRL_BREAK_EVENT 可以被發(fā)送給以包含CREATE_NEW_PROCESS
的 creationflags 形參啟動的進(jìn)程。
- Popen.terminate()?
停止子進(jìn)程。 在 POSIX 操作系統(tǒng)上,此方法會發(fā)送 SIGTERM 給子進(jìn)程。 在 Windows 上則會調(diào)用 Win32 API 函數(shù)
TerminateProcess()
來停止子進(jìn)程。
- Popen.kill()?
殺死子進(jìn)程。 在 POSIX 操作系統(tǒng)上,此函數(shù)會發(fā)送 SIGKILL 給子進(jìn)程。 在 Windows 上
kill()
則是terminate()
的別名。
以下屬性也是可用的:
- Popen.stdin?
如果 stdin 參數(shù)為
PIPE
,此屬性是一個類似open()
返回的可寫的流對象。如果 encoding 或 errors 參數(shù)被指定或者 universal_newlines 參數(shù)為True
,則此流是一個文本流,否則是字節(jié)流。如果 stdin 參數(shù)非PIPE
, 此屬性為None
。
- Popen.stdout?
如果 stdout 參數(shù)是
PIPE
,此屬性是一個類似open()
返回的可讀流。從流中讀取子進(jìn)程提供的輸出。如果 encoding 或 errors 參數(shù)被指定或者 universal_newlines 參數(shù)為True
,此流為文本流,否則為字節(jié)流。如果 stdout 參數(shù)非PIPE
,此屬性為None
。
- Popen.stderr?
如果 stderr 參數(shù)是
PIPE
,此屬性是一個類似open()
返回的可讀流。從流中讀取子進(jìn)程提供的輸出。如果 encoding 或 errors 參數(shù)被指定或者 universal_newlines 參數(shù)為True
,此流為文本流,否則為字節(jié)流。如果 stderr 參數(shù)非PIPE
,此屬性為None
。
警告
使用 communicate()
而非 .stdin.write
, .stdout.read
或者 .stderr.read
來避免由于任意其他 OS 管道緩沖區(qū)被子進(jìn)程填滿阻塞而導(dǎo)致的死鎖。
- Popen.pid?
子進(jìn)程的進(jìn)程號。
注意如果你設(shè)置了 shell 參數(shù)為
True
,則這是生成的子 shell 的進(jìn)程號。
- Popen.returncode?
此進(jìn)程的退出碼,由
poll()
和wait()
設(shè)置(以及直接由communicate()
設(shè)置)。一個None
值 表示此進(jìn)程仍未結(jié)束。一個負(fù)值
-N
表示子進(jìn)程被信號N
中斷 (僅 POSIX).
Windows Popen 助手?
STARTUPINFO
類和以下常數(shù)僅在 Windows 有效。
- class subprocess.STARTUPINFO(*, dwFlags=0, hStdInput=None, hStdOutput=None, hStdError=None, wShowWindow=0, lpAttributeList=None)?
在
Popen
創(chuàng)建時部分支持 Windows 的 STARTUPINFO 結(jié)構(gòu)。接下來的屬性僅能通過關(guān)鍵詞參數(shù)設(shè)置。在 3.7 版更改: 僅關(guān)鍵詞參數(shù)支持被加入。
- dwFlags?
一個位字段,用于確定進(jìn)程在創(chuàng)建窗口時是否使用某些
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)輸入是鍵盤緩沖區(qū)。
- hStdOutput?
如果
dwFlags
被指定為STARTF_USESTDHANDLES
,則此屬性是進(jìn)程的標(biāo)準(zhǔn)輸出句柄。除此之外,此此屬性將被忽略并且默認(rèn)標(biāo)準(zhǔn)輸出是控制臺窗口緩沖區(qū)。
- hStdError?
如果
dwFlags
被指定為STARTF_USESTDHANDLES
,則此屬性是進(jìn)程的標(biāo)準(zhǔn)錯誤句柄。除此之外,此屬性將被忽略并且默認(rèn)標(biāo)準(zhǔn)錯誤為控制臺窗口的緩沖區(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ù)時,這些句柄必須暫時地能被os.set_handle_inheritable()
繼承,否則OSError
將以 Windows errorERROR_INVALID_PARAMETER
(87) 拋出。警告
在多線程進(jìn)程中,請謹(jǐn)慎使用,以便在將此功能與對繼承所有句柄的其他進(jìn)程創(chuàng)建函數(shù)——例如
os.system()
的并發(fā)調(diào)用——相結(jié)合時,避免泄漏標(biāo)記為可繼承的句柄。這也應(yīng)用于臨時性創(chuàng)建可繼承句柄的標(biāo)準(zhǔn)句柄重定向。
3.7 新版功能.
Windows 常數(shù)?
subprocess
模塊曝出以下常數(shù)。
- subprocess.STD_INPUT_HANDLE?
標(biāo)準(zhǔn)輸入設(shè)備,這是控制臺輸入緩沖區(qū)
CONIN$
。
- subprocess.STD_OUTPUT_HANDLE?
標(biāo)準(zhǔn)輸出設(shè)備。最初,這是活動控制臺屏幕緩沖區(qū)
CONOUT$
。
- subprocess.STD_ERROR_HANDLE?
標(biāo)準(zhǔn)錯誤設(shè)備。最初,這是活動控制臺屏幕緩沖區(qū)
CONOUT$
。
- subprocess.SW_HIDE?
隱藏窗口。另一個窗口將被激活。
- subprocess.STARTF_USESTDHANDLES?
指明
STARTUPINFO.hStdInput
,STARTUPINFO.hStdOutput
和STARTUPINFO.hStdError
屬性包含額外的信息。
- subprocess.STARTF_USESHOWWINDOW?
指明
STARTUPINFO.wShowWindow
屬性包含額外的信息。
- subprocess.CREATE_NEW_CONSOLE?
新的進(jìn)程將有新的控制臺,而不是繼承父進(jìn)程的(默認(rèn))控制臺。
- subprocess.CREATE_NEW_PROCESS_GROUP?
用于指明將創(chuàng)建一個新的進(jìn)程組的
Popen
creationflags
形參。 這個旗標(biāo)對于在子進(jìn)程上使用os.kill()
來說是必須的。如果指定了
CREATE_NEW_CONSOLE
則這個旗標(biāo)會被忽略。
- subprocess.ABOVE_NORMAL_PRIORITY_CLASS?
用于指明一個新進(jìn)程將具有高于平均的優(yōu)先級的
Popen
creationflags
形參。3.7 新版功能.
- subprocess.BELOW_NORMAL_PRIORITY_CLASS?
用于指明一個新進(jìn)程將具有低于平均的優(yōu)先級的
Popen
creationflags
形參。3.7 新版功能.
- subprocess.NORMAL_PRIORITY_CLASS?
用于指明一個新進(jìn)程將具有正常(默認(rèn))優(yōu)先級的
Popen
creationflags
形參。3.7 新版功能.
- subprocess.REALTIME_PRIORITY_CLASS?
用于指明一個新進(jìn)程將具有實時優(yōu)先級的
Popen
creationflags
形參。 你應(yīng)當(dāng)幾乎永遠(yuǎn)不使用 REALTIME_PRIORITY_CLASS,因為這會中斷管理鼠標(biāo)輸入、鍵盤輸入以及后臺磁盤刷新的系統(tǒng)線程。 這個類只適用于直接與硬件“對話”,或者執(zhí)行短暫任務(wù)具有受限中斷的應(yīng)用。3.7 新版功能.
- subprocess.DETACHED_PROCESS?
指明一個新進(jìn)程將不會繼承其父控制臺的
Popen
creationflags
形參。 這個值不能與 CREATE_NEW_CONSOLE 一同使用。3.7 新版功能.
較舊的高階 API?
在 Python 3.5 之前,這三個函數(shù)組成了 subprocess 的高階 API。 現(xiàn)在你可以在許多情況下使用 run()
,但有大量現(xiàn)在代碼仍會調(diào)用這些函數(shù)。
- subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False, cwd=None, timeout=None, **other_popen_kwargs)?
運行由 args 所描述的命令。 等待命令完成,然后返回
returncode
屬性。需要捕獲 stdout 或 stderr 的代碼應(yīng)當(dāng)改用
run()
:run(...).returncode
要屏蔽 stdout 或 stderr,可提供
DEVNULL
這個值。上面顯示的參數(shù)只是常見的一些。 完整的函數(shù)簽名與
Popen
構(gòu)造器的相同 —— 此函數(shù)會將所提供的 timeout 之外的全部參數(shù)直接傳遞給目標(biāo)接口。備注
請不要在此函數(shù)中使用
stdout=PIPE
或stderr=PIPE
。 如果子進(jìn)程向管道生成了足以填滿 OS 管理緩沖區(qū)的輸出而管道還未被讀取時它將會阻塞。在 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
. TheCalledProcessError
object will have the return code in thereturncode
attribute. Ifcheck_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
這個值。上面顯示的參數(shù)只是常見的一些。 完整的函數(shù)簽名與
Popen
構(gòu)造器的相同 —— 此函數(shù)會將所提供的 timeout 之外的全部參數(shù)直接傳遞給目標(biāo)接口。備注
請不要在此函數(shù)中使用
stdout=PIPE
或stderr=PIPE
。 如果子進(jìn)程向管道生成了足以填滿 OS 管理緩沖區(qū)的輸出而管道還未被讀取時它將會阻塞。在 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ù)運行命令并返回其輸出。
如果返回碼非零則會引發(fā)
CalledProcessError
。CalledProcessError
對象將在returncode
屬性中保存返回碼并在output
屬性中保存所有輸出。這相當(dāng)于:
run(..., check=True, stdout=PIPE).stdout
上面顯示的參數(shù)只是常見的一些。 完整的函數(shù)簽名與
run()
的大致相同 —— 大部分參數(shù)會通過該接口直接傳遞。 存在一個與run()
行為不同的 API 差異:傳遞input=None
的行為將與input=b''
(或input=''
,具體取決于其他參數(shù)) 一樣而不是使用父對象的標(biāo)準(zhǔn)輸入文件處理。默認(rèn)情況下,此函數(shù)將把數(shù)據(jù)返回為已編碼的字節(jié)串。 輸出數(shù)據(jù)的實際編碼格式將取決于發(fā)起調(diào)用的命令,因此解碼為文本的操作往往需要在應(yīng)用程序?qū)蛹壣线M(jìn)行處理。
此行為可以通過設(shè)置 text, encoding, errors 或?qū)?universal_newlines 設(shè)為
True
來重載,具體描述見 常用參數(shù) 和run()
。要在結(jié)果中同時捕獲標(biāo)準(zhǔn)錯誤,請使用
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 版更改: 增加了對 input 關(guān)鍵字參數(shù)的支持。
在 3.6 版更改: 增加了 encoding 和 errors。 詳情參見
run()
。3.7 新版功能: text 作為 universal_newlines 的一個更具可讀性的別名被添加。
使用 subprocess
模塊替換舊函數(shù)?
在這一節(jié)中,"a 改為 b" 意味著 b 可以被用作 a 的替代。
備注
在這一節(jié)中的所有 "a" 函數(shù)會在找不到被執(zhí)行的程序時(差不多)靜默地失??;"b" 替代函數(shù)則會改為引發(fā) OSError
。
此外,在使用 check_output()
時如果替代函數(shù)所請求的操作產(chǎn)生了非零返回值則將失敗并引發(fā) CalledProcessError
。 操作的輸出仍能以所引發(fā)異常的 output
屬性的方式被訪問。
在下列例子中,我們假定相關(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]
啟動 p2 之后再執(zhí)行 p1.stdout.close()
調(diào)用很重要,這是為了讓 p1 能在 p2 先于 p1 退出時接收到 SIGPIPE。
另外,對于受信任的輸入,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)
注釋:
通過 shell 來調(diào)用程序通常是不必要的。
call()
返回值的編碼方式與os.system()
的不同。os.system()
函數(shù)在命令運行期間會忽略 SIGINT 和 SIGQUIT 信號,但調(diào)用方必須在使用subprocess
模塊時分別執(zhí)行此操作。
一個更現(xiàn)實的例子如下所示:
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)寫:
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
模塊的替代函數(shù)?
備注
如果 popen2 函數(shù)的 cmd 參數(shù)是一個字符串,命令會通過 /bin/sh 來執(zhí)行。 如果是一個列表,命令會被直接執(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
基本上類似于 subprocess.Popen
,不同之處在于:
舊式的 Shell 發(fā)起函數(shù)?
此模塊還提供了以下來自 2.x commands
模塊的舊版函數(shù)。 這些操作會隱式地發(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.末尾的一個換行符會從輸出中被去除。 命令的退出碼可被解讀為子進(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)。
類似于
getstatusoutput()
,但退出碼會被忽略并且返回值為包含命令輸出的字符串。 例如:>>> subprocess.getoutput('ls /bin/ls') '/bin/ls'
可用性: POSIX 和 Windows。
在 3.3.4 版更改: 添加了 Windows 支持
3.11 新版功能: Added encoding and errors arguments.
備注?
在 Windows 上將參數(shù)列表轉(zhuǎn)換為一個字符串?
在 Windows 上,args 序列會被轉(zhuǎn)換為可使用以下規(guī)則來解析的字符串(對應(yīng)于 MS C 運行時所使用的規(guī)則):
參數(shù)以空白符分隔,即空格符或制表符。
用雙引號標(biāo)示的字符串會被解讀為單個參數(shù),而不再考慮其中的空白符。 一個參數(shù)可以嵌套用引號標(biāo)示的字符串。
帶有一個反斜杠前綴的雙引號會被解讀為雙引號字面值。
反斜杠會按字面值解讀,除非它是作為雙引號的前綴。
如果反斜杠被作為雙引號的前綴,則每個反斜杠對會被解讀為一個反斜杠字面值。 如果反斜杠數(shù)量為奇數(shù),則最后一個反斜杠會如規(guī)則 3 所描述的那樣轉(zhuǎ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