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