subprocess — 子程序管理

原始碼: Lib/subprocess.py


subprocess 模組允許你生成新的程序,連線到它們的輸入/輸出/錯誤管道,並獲取它們的返回程式碼。此模組旨在替換幾個較舊的模組和函式

os.system
os.spawn*

有關如何使用 subprocess 模組替換這些模組和函式的資訊可以在以下部分找到。

參見

PEP 324 – 提出 subprocess 模組的 PEP

可用性:不是 Android,不是 iOS,不是 WASI。

此模組在 移動平臺WebAssembly 平臺上不受支援。

使用 subprocess 模組

呼叫子程序的推薦方法是使用 run() 函式來處理它可以處理的所有用例。對於更高階的用例,可以直接使用底層的 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)

執行 args 描述的命令。等待命令完成,然後返回 CompletedProcess 例項。

上面顯示的引數只是最常見的引數,在 常用引數 中描述(因此在縮寫簽名中使用僅關鍵字表示法)。完整的函式簽名與 Popen 建構函式基本相同 - 此函式的大部分引數都會傳遞到該介面。(timeoutinputcheckcapture_output 不是。)

如果 capture_output 為 true,則會捕獲 stdout 和 stderr。使用時,內部 Popen 物件會自動建立,並將 stdoutstderr 都設定為 PIPEstdoutstderr 引數不能與 capture_output 同時提供。如果你希望捕獲並將兩個流合併為一個流,請將 stdout 設定為 PIPE,將 stderr 設定為 STDOUT,而不是使用 capture_output

可以在秒內指定 timeout,它會在內部傳遞給 Popen.communicate()。如果超時到期,子程序將被殺死並等待。在子程序終止後,將重新引發 TimeoutExpired 異常。在許多平臺 API 上,初始程序建立本身無法中斷,因此在程序建立需要多長時間之後,你至少才能看到超時異常。

input 引數會傳遞給 Popen.communicate(),進而傳遞給子程序的標準輸入 (stdin)。如果使用該引數,則必須是位元組序列,或者如果指定了 encodingerrors,或者 text 為 true,則必須是字串。當使用此引數時,內部的 Popen 物件會自動建立,並將 stdin 設定為 PIPE,並且不能同時使用 stdin 引數。

如果 check 為 true,並且程序以非零退出程式碼退出,則會引發 CalledProcessError 異常。該異常的屬性會儲存引數、退出程式碼以及捕獲的 stdout 和 stderr。

如果指定了 encodingerrors,或者 text 為 true,則用於 stdin、stdout 和 stderr 的檔案物件將以文字模式開啟,並使用指定的 encodingerrors 或者 io.TextIOWrapper 預設值。universal_newlines 引數等效於 text,為了向後相容而提供。預設情況下,檔案物件以二進位制模式開啟。

如果 env 不是 None,則它必須是一個對映,定義新程序的環境變數;這些環境變數將代替繼承當前程序環境的預設行為。它直接傳遞給 Popen。此對映可以是任何平臺上的 str 到 str,或者像 os.environos.environb 一樣,是 POSIX 平臺上的 bytes 到 bytes。

示例

>>> 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 的更易理解的別名。添加了 capture_output 引數。

在 3.12 版本中變更: 更改了 shell=True 的 Windows shell 搜尋順序。當前目錄和 %PATH% 被替換為 %COMSPEC%%SystemRoot%\System32\cmd.exe。因此,將名為 cmd.exe 的惡意程式放入當前目錄不再有效。

class subprocess.CompletedProcess

run() 的返回值,表示已完成的程序。

args

用於啟動程序的引數。 這可以是一個列表或一個字串。

returncode

子程序的退出狀態。 通常,退出狀態為 0 表示它已成功執行。

負值 -N 表示子程序因訊號 N 而終止(僅限 POSIX)。

stdout

從子程序捕獲的 stdout。 位元組序列,或者如果呼叫 run() 時使用了 encoding、errors 或 text=True,則為字串。 如果未捕獲 stdout,則為 None

如果使用 stderr=subprocess.STDOUT 執行該程序,則 stdout 和 stderr 將在此屬性中合併,並且 stderr 將為 None

stderr

從子程序捕獲的 stderr。 位元組序列,或者如果呼叫 run() 時使用了 encoding、errors 或 text=True,則為字串。 如果未捕獲 stderr,則為 None

check_returncode()

如果 returncode 為非零值,則引發 CalledProcessError

3.5 版本新增。

subprocess.DEVNULL

可以作為 Popenstdinstdoutstderr 引數使用的特殊值,表示將使用特殊檔案 os.devnull

3.3 版本新增。

subprocess.PIPE

可以作為 Popenstdinstdoutstderr 引數使用的特殊值,表示應該開啟通向標準流的管道。 與 Popen.communicate() 一起使用最為有效。

subprocess.STDOUT

可以作為 Popenstderr 引數使用的特殊值,表示標準錯誤應該與標準輸出使用相同的控制代碼。

exception subprocess.SubprocessError

此模組中所有其他異常的基類。

3.3 版本新增。

exception subprocess.TimeoutExpired

SubprocessError 的子類,當等待子程序時超時過期時引發。

cmd

用於生成子程序的命令。

timeout

以秒為單位的超時時間。

output

如果子程序被 run()check_output() 捕獲,則為子程序的輸出。 否則,為 None。 當捕獲到任何輸出時,這始終是 bytes,無論 text=True 設定如何。當沒有觀察到輸出時,它可能會保持為 None 而不是 b''

stdout

與 output 的別名,與 stderr 對稱。

stderr

如果子程序被 run() 捕獲,則為子程序的 stderr 輸出。 否則,為 None。 當捕獲到 stderr 輸出時,這始終是 bytes,無論 text=True 設定如何。當沒有觀察到 stderr 輸出時,它可能會保持為 None 而不是 b''

3.3 版本新增。

在 3.5 版本中變更: 添加了 stdoutstderr 屬性

exception subprocess.CalledProcessError

SubprocessError 的子類,當由 check_call(), check_output(), 或 run() (且 check=True) 執行的程序返回非零退出狀態時引發。

returncode

子程序的退出狀態。如果程序由於訊號而退出,這將是負的訊號編號。

cmd

用於生成子程序的命令。

output

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

stdout

stderr 對稱的輸出別名。

stderr

如果子程序的 stderr 輸出被 run() 捕獲,則為子程序的 stderr 輸出。否則,為 None

在 3.5 版本中變更: 添加了 stdoutstderr 屬性

常用引數

為了支援各種用例,Popen 建構函式(以及便利函式)接受大量可選引數。對於大多數典型用例,這些引數中的許多引數都可以安全地保留其預設值。最常用的引數有

所有呼叫都必須使用 *args*,它應該是一個字串或一個程式引數序列。通常首選提供引數序列,因為它允許模組處理任何所需的引數轉義和引用(例如,允許檔名中包含空格)。如果傳遞單個字串,則 *shell* 必須為 True(見下文),否則該字串必須只指定要執行的程式,而不指定任何引數。

*stdin*、*stdout* 和 *stderr* 分別指定已執行程式的標準輸入、標準輸出和標準錯誤檔案控制代碼。有效值為 NonePIPEDEVNULL、現有檔案描述符(正整數)和一個具有有效檔案描述符的現有 檔案物件。 使用 None 的預設設定,不會發生重定向。 PIPE 表示應建立一個到子程序的新管道。 DEVNULL 表示將使用特殊檔案 os.devnull。此外,*stderr* 可以是 STDOUT,表示子程序的 stderr 資料應捕獲到與 *stdout* 相同的檔案控制代碼中。

如果指定了 *encoding* 或 *errors*,或者 *text* (也稱為 *universal_newlines*)為真,則檔案物件 *stdin*、*stdout* 和 *stderr* 將以文字模式開啟,並使用呼叫中指定的 *encoding* 和 *errors* 或 io.TextIOWrapper 的預設值。

對於 *stdin*,輸入中的換行符 '\n' 將轉換為預設行分隔符 os.linesep。對於 *stdout* 和 *stderr*,輸出中的所有換行符都將轉換為 '\n'。有關詳細資訊,請參閱當建構函式的 *newline* 引數為 None 時,io.TextIOWrapper 類的文件。

如果未使用文字模式,則 *stdin*、*stdout* 和 *stderr* 將作為二進位制流開啟。不執行編碼或換行符轉換。

在 3.6 版本中更改: 添加了 *encoding* 和 *errors* 引數。

在 3.7 版本中更改: 添加了 *text* 引數作為 *universal_newlines* 的別名。

注意

檔案物件 Popen.stdinPopen.stdoutPopen.stderr 的 newlines 屬性不會被 Popen.communicate() 方法更新。

如果 *shell* 為 True,則指定的命令將透過 shell 執行。如果您主要使用 Python 來增強對大多數系統 shell 的控制流,並且仍然希望方便地訪問其他 shell 功能(例如 shell 管道、檔名萬用字元、環境變數擴充套件以及將 ~ 擴充套件為使用者的 home 目錄),這可能很有用。但是,請注意,Python 本身提供了許多類似 shell 的功能的實現(特別是 globfnmatchos.walk()os.path.expandvars()os.path.expanduser()shutil)。

在 3.3 版本中更改: 當 *universal_newlines* 為 True 時,該類使用編碼 locale.getpreferredencoding(False) 而不是 locale.getpreferredencoding()。有關此更改的更多資訊,請參閱 io.TextIOWrapper 類。

注意

在使用 shell=True 之前,請閱讀安全注意事項 部分。

這些選項以及所有其他選項都在 Popen 建構函式文件中進行了更詳細的描述。

Popen 建構函式

此模組中底層程序的建立和管理由 Popen 類處理。它提供了很大的靈活性,因此開發人員能夠處理便利函式未涵蓋的較不常見的情況。

class subprocess.Popen(args, bufsize=-1, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=True, shell=False, cwd=None, env=None, universal_newlines=None, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False, pass_fds=(), *, group=None, extra_groups=None, user=None, umask=-1, encoding=None, errors=None, text=None, pipesize=-1, process_group=None)

在新程序中執行子程式。在 POSIX 系統上,該類使用類似於 os.execvpe() 的行為來執行子程式。在 Windows 系統上,該類使用 Windows 的 CreateProcess() 函式。Popen 的引數如下。

args 應該是一個程式引數序列,或者是一個單獨的字串或路徑類物件。預設情況下,如果 args 是一個序列,則要執行的程式是 args 中的第一項。如果 args 是一個字串,則其解釋取決於平臺,如下所述。有關與預設行為的其他差異,請參閱 shellexecutable 引數。除非另有說明,建議將 args 作為序列傳遞。

警告

為了獲得最大的可靠性,請為可執行檔案使用完全限定的路徑。要在 PATH 上搜索非限定名稱,請使用 shutil.which()。在所有平臺上,傳遞 sys.executable 是再次啟動當前 Python 直譯器的推薦方法,並使用 -m 命令列格式啟動已安裝的模組。

解析 executable(或 args 的第一項)的路徑取決於平臺。對於 POSIX 系統,請參閱 os.execvpe(),並注意在解析或搜尋可執行檔案路徑時,cwd 會覆蓋當前工作目錄,而 env 可以覆蓋 PATH 環境變數。對於 Windows 系統,請參閱 WinAPI CreateProcesslpApplicationNamelpCommandLine 引數的文件,並注意當使用 shell=False 解析或搜尋可執行檔案路徑時,cwd 不會覆蓋當前工作目錄,而 env 不能覆蓋 PATH 環境變數。使用完整路徑可以避免所有這些差異。

下面是將一些引數作為序列傳遞給外部程式的示例:

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

在 POSIX 系統上,如果 args 是一個字串,則該字串將被解釋為要執行的程式的名稱或路徑。但是,只有在不向程式傳遞引數時才能執行此操作。

注意

可能不清楚如何將 shell 命令分解為引數序列,尤其是在複雜的情況下。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)會放入單獨的列表元素中,而當在 shell 中使用時需要引號或反斜槓轉義的引數(如包含空格的檔名或上面顯示的 echo 命令)則是單個列表元素。

在 Windows 系統上,如果 args 是一個序列,它將被轉換為字串,轉換方式在 在 Windows 上將引數序列轉換為字串 中描述。這是因為底層的 CreateProcess() 操作字串。

在 3.6 版本中更改: 如果 shellFalse,則 args 引數接受路徑類物件,在 POSIX 系統上接受包含路徑類物件的序列。

在 3.8 版本中更改: 如果 shellFalse,則 args 引數接受路徑類物件,在 Windows 系統上接受包含位元組和路徑類物件的序列。

shell 引數(預設為 False)指定是否將 shell 用作要執行的程式。如果 shellTrue,建議將 args 作為字串而不是序列傳遞。

shell=True 的 POSIX 系統上,shell 預設為 /bin/sh。如果 args 是一個字串,則該字串指定透過 shell 執行的命令。這意味著該字串的格式必須與在 shell 提示符下鍵入的格式完全相同。這包括,例如,對包含空格的檔名進行引用或反斜槓轉義。如果 args 是一個序列,則第一項指定命令字串,任何其他項都將被視為 shell 本身的附加引數。也就是說,Popen 的作用等同於

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

shell=True 的 Windows 系統上,COMSPEC 環境變數指定預設 shell。在 Windows 上,唯一需要指定 shell=True 的情況是,當要執行的命令內置於 shell 中時(例如 dircopy)。您不需要 shell=True 來執行批處理檔案或基於控制檯的可執行檔案。

注意

在使用 shell=True 之前,請閱讀安全注意事項 部分。

當建立 stdin/stdout/stderr 管道檔案物件時,bufsize 將作為相應的引數提供給 open() 函式

  • 0 表示無緩衝(讀取和寫入是一個系統呼叫,並且可以返回較短的內容)

  • 1 表示行緩衝(僅當 text=Trueuniversal_newlines=True 時可用)

  • 任何其他正值表示使用近似於該大小的緩衝區

  • 負的 bufsize(預設值)表示將使用系統預設的 io.DEFAULT_BUFFER_SIZE。

在 3.3.1 版本中更改: bufsize 現在預設為 -1,以預設啟用緩衝,以匹配大多數程式碼期望的行為。在 Python 3.2.4 和 3.3.1 之前的版本中,它錯誤地預設為 0,這是無緩衝的並允許短讀取。這是無意的,並且與大多數程式碼期望的 Python 2 的行為不匹配。

executable 引數指定要執行的替換程式。它很少需要。當 shell=False 時,executable 將替換由 args 指定的要執行的程式。但是,原始的 args 仍然傳遞給該程式。大多數程式將 args 指定的程式視為命令名稱,這可能與實際執行的程式不同。在 POSIX 系統上,args 名稱將成為可執行檔案在 ps 等實用程式中的顯示名稱。如果 shell=True,則在 POSIX 系統上,executable 引數指定預設 /bin/sh 的替換 shell。

在 3.6 版本中更改: executable 引數在 POSIX 系統上接受路徑類物件

在 3.8 版本中更改: executable 引數在 Windows 系統上接受位元組串和路徑類物件

在 3.12 版本中變更: 更改了 shell=True 的 Windows shell 搜尋順序。當前目錄和 %PATH% 被替換為 %COMSPEC%%SystemRoot%\System32\cmd.exe。因此,將名為 cmd.exe 的惡意程式放入當前目錄不再有效。

stdinstdoutstderr 分別指定已執行程式的標準輸入、標準輸出和標準錯誤檔案控制代碼。有效值是 NonePIPEDEVNULL,現有檔案描述符(正整數)和一個具有有效檔案描述符的現有 檔案物件。使用 None 的預設設定,不會發生重定向。PIPE 表示應該為子程序建立一個新的管道。DEVNULL 表示將使用特殊檔案 os.devnull。此外,stderr 可以是 STDOUT,這表示應用程式的標準錯誤資料應捕獲到與 stdout 相同的檔案控制代碼中。

如果 preexec_fn 設定為可呼叫物件,則此物件將在子程序執行之前在子程序中呼叫。(僅限 POSIX)

警告

在應用程式中存線上程的情況下,使用 preexec_fn 引數是不安全的。子程序可能會在呼叫 exec 之前發生死鎖。

注意

如果需要修改子程序的環境,請使用 env 引數,而不是在 preexec_fn 中執行此操作。start_new_sessionprocess_group 引數應取代使用 preexec_fn 呼叫 os.setsid()os.setpgid() 在子程序中的程式碼。

在 3.8 版本中更改: 子直譯器中不再支援 preexec_fn 引數。在子直譯器中使用該引數會引發 RuntimeError。新的限制可能會影響部署在 mod_wsgi、uWSGI 和其他嵌入式環境中的應用程式。

如果 close_fds 為 true,則除了 012 之外的所有檔案描述符都將在子程序執行之前關閉。否則,當 close_fds 為 false 時,檔案描述符將按照 檔案描述符的繼承 中的描述遵守其可繼承標誌。

在 Windows 系統上,如果 close_fds 為 true,則除非在 STARTUPINFO.lpAttributeListhandle_list 元素中顯式傳遞或透過標準控制代碼重定向,否則子程序將不會繼承任何控制代碼。

在 3.2 版本中更改: close_fds 的預設值從 False 更改為上述描述的值。

在 3.7 版本中更改: 在 Windows 系統上,當重定向標準控制代碼時,close_fds 的預設值從 False 更改為 True。現在可以在重定向標準控制代碼時將 close_fds 設定為 True

pass_fds 是一個可選的檔案描述符序列,用於在父程序和子程序之間保持開啟狀態。提供任何 pass_fds 都會強制 close_fdsTrue。(僅限 POSIX)

在 3.2 版本中更改: 添加了 pass_fds 引數。

如果 cwd 不是 None,則該函式會在執行子程序之前將工作目錄更改為 cwdcwd 可以是字串、位元組串或 路徑類物件。在 POSIX 系統上,如果可執行檔案路徑是相對路徑,則該函式會在相對於 cwd 的位置查詢 executable(或 args 中的第一項)。

在 3.6 版本中更改: cwd 引數在 POSIX 系統上接受路徑類物件

在 3.7 版本中更改: cwd 引數在 Windows 系統上接受路徑類物件

在 3.8 版本中更改: cwd 引數在 Windows 系統上接受位元組串物件。

如果 restore_signals 為 true(預設值),則 Python 已設定為 SIG_IGN 的所有訊號將在 exec 之前在子程序中恢復為 SIG_DFL。目前,這包括 SIGPIPE、SIGXFZ 和 SIGXFSZ 訊號。(僅限 POSIX)

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

如果 start_new_session 為 true,則將在子程序執行之前在子程序中呼叫 setsid() 系統呼叫。

可用性:POSIX

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

如果 process_group 是一個非負整數,則將在子程序執行之前在子程序中呼叫 setpgid(0, value) 系統呼叫。

可用性:POSIX

在 3.11 版本中更改: 添加了 process_group

如果 group 不是 None,則將在子程序執行之前在子程序中呼叫 setregid() 系統呼叫。如果提供的值是字串,則將透過 grp.getgrnam() 查詢該值,並使用 gr_gid 中的值。如果該值是整數,則將按原樣傳遞。(僅限 POSIX)

可用性:POSIX

在 3.9 版本中新增。

如果 extra_groups 不是 None,則將在子程序執行之前在子程序中呼叫 setgroups() 系統呼叫。extra_groups 中提供的字串將透過 grp.getgrnam() 查詢,並使用 gr_gid 中的值。整數值將按原樣傳遞。(僅限 POSIX)

可用性:POSIX

在 3.9 版本中新增。

如果 user 不是 None,則將在子程序執行之前在子程序中呼叫 setreuid() 系統呼叫。如果提供的值是字串,則將透過 pwd.getpwnam() 查詢該值,並使用 pw_uid 中的值。如果該值是整數,則將按原樣傳遞。(僅限 POSIX)

可用性:POSIX

在 3.9 版本中新增。

如果 umask 不是負數,則將在子程序執行之前在子程序中呼叫 umask() 系統呼叫。

可用性:POSIX

在 3.9 版本中新增。

如果 env 不是 None,它必須是一個對映,用於定義新程序的環境變數;這些變數將代替繼承當前程序環境的預設行為。此對映可以在任何平臺上使用字串到字串,或者在 POSIX 平臺上使用位元組串到位元組串,與 os.environos.environb 非常相似。

注意

如果指定了 env,則 env 必須提供程式執行所需的任何變數。在 Windows 系統上,為了執行並行程式集,指定的 env **必須**包含有效的 SystemRoot

如果指定了 encodingerrors,或者 text 為 true,則檔案物件 stdinstdoutstderr 將以文字模式開啟,並使用指定的 encodingerrors,如上文常用引數中所述。universal_newlines 引數等效於 text,並且是為了向後相容而提供的。預設情況下,檔案物件以二進位制模式開啟。

3.6 版本新增: 添加了 encodingerrors 引數。

3.7 版本新增: 添加了 text 引數,作為 universal_newlines 更易讀的別名。

如果給定 startupinfo,它將是一個 STARTUPINFO 物件,該物件將傳遞給底層的 CreateProcess 函式。

如果給定 creationflags,則可以是一個或多個以下標誌:

stdin, stdoutstderr 使用 PIPE 時,可以使用 pipesize 來更改管道的大小。 管道的大小僅在支援此功能的平臺上更改(目前編寫時僅限 Linux)。其他平臺將忽略此引數。

3.10 版本更改: 添加了 pipesize 引數。

Popen 物件透過 with 語句支援作為上下文管理器:在退出時,標準檔案描述符將被關閉,並且程序將被等待。

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

Popen 以及此模組中其他使用它的函式會引發一個 審計事件 subprocess.Popen,其中包含引數 executable, args, cwdenvargs 的值可能是一個單獨的字串或一個字串列表,具體取決於平臺。

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

3.6 版本更改: 如果子程序仍在執行,Popen 解構函式現在會發出一個 ResourceWarning 警告。

3.8 版本更改: 在某些情況下,Popen 可以使用 os.posix_spawn() 以獲得更好的效能。在 Windows Linux 子系統和 QEMU 使用者模擬中,使用 os.posix_spawn() 的 Popen 建構函式不再在出現類似程式缺失的錯誤時引發異常,而是子程序會以非零的 returncode 失敗。

異常

在子程序中,在新的程式開始執行之前引發的異常,將在父程序中重新引發。

最常見的引發的異常是 OSError。例如,當嘗試執行不存在的檔案時會發生這種情況。應用程式應為 OSError 異常做好準備。請注意,當 shell=True 時,僅當找不到選定的 shell 本身時,子程序才會引發 OSError。要確定 shell 是否未能找到請求的應用程式,有必要檢查子程序的返回程式碼或輸出。

如果使用無效的引數呼叫 Popen,則會引發 ValueError

如果被呼叫的程序返回非零返回程式碼,check_call()check_output() 將引發 CalledProcessError

所有接受 timeout 引數的函式和方法,如 run()Popen.communicate(),如果超時在程序退出前過期,則會引發 TimeoutExpired

此模組中定義的所有異常都繼承自 SubprocessError

3.3 版本新增: 添加了 SubprocessError 基類。

安全注意事項

與其他一些 popen 函式不同,此庫不會隱式選擇呼叫系統 shell。這意味著所有字元,包括 shell 元字元,都可以安全地傳遞給子程序。如果透過 shell=True 顯式呼叫 shell,則應用程式有責任確保所有空格和元字元都適當地引用,以避免 shell 注入 漏洞。在某些平臺上,可以使用 shlex.quote() 進行此轉義。

在 Windows 上,批處理檔案(*.bat*.cmd)可能會被作業系統在系統 shell 中啟動,而不管傳遞給此庫的引數如何。這可能會導致引數根據 shell 規則進行解析,而 Python 不會新增任何轉義。如果您有意使用來自不可信來源的引數啟動批處理檔案,請考慮傳遞 shell=True 以允許 Python 轉義特殊字元。有關其他討論,請參閱 gh-114539

Popen 物件

Popen 類的例項具有以下方法:

Popen.poll()

檢查子程序是否已終止。設定並返回 returncode 屬性。否則,返回 None

Popen.wait(timeout=None)

等待子程序終止。設定並返回 returncode 屬性。

如果程序在 timeout 秒後未終止,則引發 TimeoutExpired 異常。可以安全地捕獲此異常並重試等待。

注意

當使用 stdout=PIPEstderr=PIPE 且子程序生成足夠多的輸出到管道,以至於它阻塞等待作業系統管道緩衝區接受更多資料時,這將導致死鎖。在使用管道時使用 Popen.communicate() 來避免這種情況。

注意

timeout 引數不是 None 時,則(在 POSIX 上)該函式是使用忙迴圈(非阻塞呼叫和短睡眠)實現的。使用 asyncio 模組進行非同步等待:請參閱 asyncio.create_subprocess_exec

3.3 版本更改: 添加了 timeout 引數。

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

與程序互動:向 stdin 傳送資料,從 stdout 和 stderr 讀取資料,直到檔案末尾。等待程序終止並設定 returncode 屬性。可選的 input 引數應該是要傳送給子程序的資料,或者 None,如果不需要向子程序傳送任何資料。如果流以文字模式開啟,則 input 必須是字串。否則,它必須是位元組。

communicate() 返回一個元組 (stdout_data, stderr_data)。如果流以文字模式開啟,則資料將是字串;否則,資料將是位元組。

請注意,如果要向程序的 stdin 傳送資料,則需要使用 stdin=PIPE 建立 Popen 物件。類似地,要在結果元組中獲得除 None 以外的任何內容,還需要提供 stdout=PIPE 和/或 stderr=PIPE

如果程序在 timeout 秒後沒有終止,將引發 TimeoutExpired 異常。捕獲此異常並重試通訊不會丟失任何輸出。

如果超時過期,子程序不會被殺死,因此為了正確清理,一個行為良好的應用程式應該殺死子程序並完成通訊

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

注意

讀取的資料會快取在記憶體中,因此如果資料大小很大或無限,請勿使用此方法。

3.3 版本更改: 添加了 timeout 引數。

Popen.send_signal(signal)

向子程序傳送訊號 signal

如果程序已完成,則不執行任何操作。

注意

在 Windows 上,SIGTERM 是 terminate() 的別名。可以將 CTRL_C_EVENT 和 CTRL_BREAK_EVENT 傳送到使用包含 CREATE_NEW_PROCESS_GROUPcreationflags 引數啟動的程序。

Popen.terminate()

停止子程序。在 POSIX 作業系統上,該方法會向子程序傳送 SIGTERM。在 Windows 上,呼叫 Win32 API 函式 TerminateProcess() 來停止子程序。

Popen.kill()

殺死子程序。在 POSIX 作業系統上,該函式會向子程序傳送 SIGKILL。在 Windows 上,kill()terminate() 的別名。

該類還會設定以下屬性供您訪問。不支援將它們重新分配為新值

Popen.args

傳遞給 Popenargs 引數 – 一個程式引數序列或單個字串。

3.3 版本新增。

Popen.stdin

如果 stdin 引數是 PIPE,則此屬性是由 open() 返回的可寫流物件。如果指定了 encodingerrors 引數,或者 textuniversal_newlines 引數是 True,則該流是文字流,否則是位元組流。如果 stdin 引數不是 PIPE,則此屬性為 None

Popen.stdout

如果 stdout 引數是 PIPE,則此屬性是由 open() 返回的可讀流物件。從流讀取可以提供來自子程序的輸出。如果指定了 encodingerrors 引數,或者 textuniversal_newlines 引數是 True,則該流是文字流,否則是位元組流。如果 stdout 引數不是 PIPE,則此屬性為 None

Popen.stderr

如果 stderr 引數是 PIPE,則此屬性是由 open() 返回的可讀流物件。從流讀取可以提供來自子程序的錯誤輸出。如果指定了 encodingerrors 引數,或者 textuniversal_newlines 引數是 True,則該流是文字流,否則是位元組流。如果 stderr 引數不是 PIPE,則此屬性為 None

警告

請使用 communicate() 而不是 .stdin.write.stdout.read.stderr.read,以避免由於任何其他作業系統管道緩衝區已滿而導致子程序阻塞的死鎖。

Popen.pid

子程序的程序 ID。

請注意,如果將 shell 引數設定為 True,則這是生成的外殼的程序 ID。

Popen.returncode

子程序返回程式碼。初始值為 None,如果 poll()wait()communicate() 方法檢測到程序已終止,則會設定 returncode

None 值表示在上次方法呼叫時程序尚未終止。

負值 -N 表示子程序因訊號 N 而終止(僅限 POSIX)。

Windows Popen 幫助程式

STARTUPINFO 類和以下常量僅在 Windows 上可用。

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

Windows STARTUPINFO 結構的部分支援用於建立 Popen。可以透過將以下屬性作為僅關鍵字引數傳遞來設定。

在 3.7 版本中更改: 添加了僅關鍵字引數支援。

dwFlags

一個位欄位,用於確定在程序建立視窗時是否使用某些 STARTUPINFO 屬性。

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

如果 dwFlags 指定了 STARTF_USESTDHANDLES,則此屬性是該程序的標準輸入控制代碼。如果未指定 STARTF_USESTDHANDLES,則標準輸入的預設值是鍵盤緩衝區。

hStdOutput

如果 dwFlags 指定了 STARTF_USESTDHANDLES,則此屬性是該程序的標準輸出控制代碼。否則,將忽略此屬性,並且標準輸出的預設值是控制檯視窗的緩衝區。

hStdError

如果 dwFlags 指定了 STARTF_USESTDHANDLES,則此屬性是該程序的標準錯誤控制代碼。否則,將忽略此屬性,並且標準錯誤的預設值是控制檯視窗的緩衝區。

wShowWindow

如果 dwFlags 指定了 STARTF_USESHOWWINDOW,則此屬性可以是 ShowWindow 函式的 nCmdShow 引數中可以指定的任何值,除了 SW_SHOWDEFAULT。否則,將忽略此屬性。

SW_HIDE 為此屬性提供。 當 Popen 使用 shell=True 呼叫時會用到它。

lpAttributeList

STARTUPINFOEX 中給出的用於程序建立的附加屬性的字典,請參閱 UpdateProcThreadAttribute

支援的屬性

handle_list

將被繼承的控制代碼序列。 如果非空,則 *close_fds* 必須為 true。

當傳遞給 Popen 建構函式時,控制代碼必須透過 os.set_handle_inheritable() 臨時設定為可繼承的,否則會引發帶有 Windows 錯誤 ERROR_INVALID_PARAMETER (87) 的 OSError

警告

在多執行緒程序中,當將此功能與併發呼叫其他繼承所有控制代碼的程序建立函式(例如 os.system())結合使用時,請注意避免洩漏標記為可繼承的控制代碼。 這也適用於標準控制代碼重定向,它會臨時建立可繼承的控制代碼。

在 3.7 版本中新增。

Windows 常量

subprocess 模組公開了以下常量。

subprocess.STD_INPUT_HANDLE

標準輸入裝置。 最初,這是控制檯輸入緩衝區 CONIN$

subprocess.STD_OUTPUT_HANDLE

標準輸出裝置。 最初,這是活動的控制檯螢幕緩衝區 CONOUT$

subprocess.STD_ERROR_HANDLE

標準錯誤裝置。 最初,這是活動的控制檯螢幕緩衝區 CONOUT$

subprocess.SW_HIDE

隱藏視窗。 將啟用另一個視窗。

subprocess.STARTF_USESTDHANDLES

指定 STARTUPINFO.hStdInputSTARTUPINFO.hStdOutputSTARTUPINFO.hStdError 屬性包含附加資訊。

subprocess.STARTF_USESHOWWINDOW

指定 STARTUPINFO.wShowWindow 屬性包含附加資訊。

subprocess.STARTF_FORCEONFEEDBACK

用於指定在程序啟動時顯示 *正在後臺工作* 滑鼠游標的 STARTUPINFO.dwFlags 引數。 這是 GUI 程序的預設行為。

在 3.13 版本中新增。

subprocess.STARTF_FORCEOFFFEEDBACK

用於指定在啟動程序時不更改滑鼠游標的 STARTUPINFO.dwFlags 引數。

在 3.13 版本中新增。

subprocess.CREATE_NEW_CONSOLE

新程序具有新的控制檯,而不是繼承其父程序的控制檯(預設值)。

subprocess.CREATE_NEW_PROCESS_GROUP

一個 Popen creationflags 引數,用於指定將建立一個新的程序組。此標誌對於在子程序上使用 os.kill() 是必需的。

如果指定了 CREATE_NEW_CONSOLE,則將忽略此標誌。

subprocess.ABOVE_NORMAL_PRIORITY_CLASS

一個 Popen creationflags 引數,用於指定新程序將具有高於平均值的優先順序。

在 3.7 版本中新增。

subprocess.BELOW_NORMAL_PRIORITY_CLASS

一個 Popen creationflags 引數,用於指定新程序將具有低於平均值的優先順序。

在 3.7 版本中新增。

subprocess.HIGH_PRIORITY_CLASS

一個 Popen creationflags 引數,用於指定新程序將具有高優先順序。

在 3.7 版本中新增。

subprocess.IDLE_PRIORITY_CLASS

一個 Popen creationflags 引數,用於指定新程序將具有空閒(最低)優先順序。

在 3.7 版本中新增。

subprocess.NORMAL_PRIORITY_CLASS

一個 Popen creationflags 引數,用於指定新程序將具有正常優先順序。(預設)

在 3.7 版本中新增。

subprocess.REALTIME_PRIORITY_CLASS

一個 Popen creationflags 引數,用於指定新程序將具有即時優先順序。 您幾乎永遠不應使用 REALTIME_PRIORITY_CLASS,因為這會中斷管理滑鼠輸入、鍵盤輸入和後臺磁碟重新整理的系統執行緒。 此類適用於直接與硬體“對話”或執行應限制中斷的短暫任務的應用程式。

在 3.7 版本中新增。

subprocess.CREATE_NO_WINDOW

一個 Popen creationflags 引數,用於指定新程序不會建立視窗。

在 3.7 版本中新增。

subprocess.DETACHED_PROCESS

一個 Popen creationflags 引數,用於指定新程序不會繼承其父程序的控制檯。此值不能與 CREATE_NEW_CONSOLE 一起使用。

在 3.7 版本中新增。

subprocess.CREATE_DEFAULT_ERROR_MODE

一個 Popen creationflags 引數,用於指定新程序不繼承呼叫程序的錯誤模式。相反,新程序會獲得預設的錯誤模式。此功能對於停用硬錯誤的執行多執行緒 Shell 應用程式特別有用。

在 3.7 版本中新增。

subprocess.CREATE_BREAKAWAY_FROM_JOB

一個 Popen creationflags 引數,用於指定新程序不與作業關聯。

在 3.7 版本中新增。

舊的高階 API

在 Python 3.5 之前,這三個函式組成了 subprocess 的高階 API。現在您可以在許多情況下使用 run(),但很多現有程式碼都呼叫這些函式。

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 的值。

上面顯示的引數只是一些常見的引數。完整的函式簽名與 Popen 建構函式的簽名相同 - 此函式將除 timeout 之外的所有提供的引數直接傳遞給該介面。

注意

不要將 stdout=PIPEstderr=PIPE 與此函式一起使用。如果子程序生成足夠多的輸出到管道以填滿作業系統管道緩衝區,則子程序將會阻塞,因為沒有從管道讀取資料。

3.3 版本更改: 添加了 timeout 引數。

在 3.12 版本中變更: 更改了 shell=True 的 Windows shell 搜尋順序。當前目錄和 %PATH% 被替換為 %COMSPEC%%SystemRoot%\System32\cmd.exe。因此,將名為 cmd.exe 的惡意程式放入當前目錄不再有效。

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

執行帶有引數的命令。等待命令完成。如果返回程式碼為零,則返回,否則引發 CalledProcessErrorCalledProcessError 物件將在 returncode 屬性中包含返回程式碼。如果 check_call() 無法啟動程序,它將傳播引發的異常。

需要捕獲 stdout 或 stderr 的程式碼應改用 run()

run(..., check=True)

要禁止 stdout 或 stderr,請提供 DEVNULL 的值。

上面顯示的引數只是一些常見的引數。完整的函式簽名與 Popen 建構函式的簽名相同 - 此函式將除 timeout 之外的所有提供的引數直接傳遞給該介面。

注意

不要將 stdout=PIPEstderr=PIPE 與此函式一起使用。如果子程序生成足夠多的輸出到管道以填滿作業系統管道緩衝區,則子程序將會阻塞,因為沒有從管道讀取資料。

3.3 版本更改: 添加了 timeout 引數。

在 3.12 版本中變更: 更改了 shell=True 的 Windows shell 搜尋順序。當前目錄和 %PATH% 被替換為 %COMSPEC%%SystemRoot%\System32\cmd.exe。因此,將名為 cmd.exe 的惡意程式放入當前目錄不再有效。

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)

執行帶有引數的命令並返回其輸出。

如果返回程式碼為非零值,則會引發 CalledProcessErrorCalledProcessError 物件將在 returncode 屬性中包含返回程式碼,並在 output 屬性中包含任何輸出。

這等效於

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

上面顯示的引數只是一些常見的引數。完整的函式簽名與 run() 的簽名基本相同 - 大部分引數都直接傳遞給該介面。與 run() 行為的一個 API 偏差是:傳遞 input=None 的行為與 input=b'' (或 input='',具體取決於其他引數) 相同,而不是使用父級的標準輸入檔案控制代碼。

預設情況下,此函式將以編碼的位元組形式返回資料。輸出資料的實際編碼可能取決於被呼叫的命令,因此通常需要在應用程式級別處理文字的解碼。

可以透過將 textencodingerrorsuniversal_newlines 設定為 True 來覆蓋此行為,如 常用引數run() 中所述。

要同時捕獲結果中的標準錯誤,請使用 stderr=subprocess.STDOUT

>>> subprocess.check_output(
...     "ls non_existent_file; exit 0",
...     stderr=subprocess.STDOUT,
...     shell=True)
'ls: non_existent_file: No such file or directory\n'

在 3.1 版本中新增。

3.3 版本更改: 添加了 timeout 引數。

在 3.4 版本中更改: 添加了對 input 關鍵字引數的支援。

在 3.6 版本中更改: 添加了 encodingerrors。有關詳細資訊,請參閱 run()

3.7 版本新增: 添加了 text 引數,作為 universal_newlines 更易讀的別名。

在 3.12 版本中變更: 更改了 shell=True 的 Windows shell 搜尋順序。當前目錄和 %PATH% 被替換為 %COMSPEC%%SystemRoot%\System32\cmd.exe。因此,將名為 cmd.exe 的惡意程式放入當前目錄不再有效。

subprocess 模組替換舊函式

在本節中,“a 變為 b”表示 b 可以用作 a 的替代。

注意

如果找不到要執行的程式,本節中的所有 “a” 函式都會(或多或少)靜默失敗;“b” 替代項則會引發 OSError

此外,如果請求的操作產生非零的返回碼,使用 check_output() 的替換操作將會失敗,並丟擲 CalledProcessError 異常。輸出仍然可以透過丟擲的異常的 output 屬性訪問。

在下面的示例中,我們假設相關的函式已經從 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]

在啟動 p2 之後呼叫 p1.stdout.close() 非常重要,這樣如果 p2 在 p1 之前退出,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 呼叫程式。

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

  • os.system() 函式在命令執行時會忽略 SIGINT 和 SIGQUIT 訊號,但是當使用 subprocess 模組時,呼叫者必須單獨處理這些訊號。

一個更實際的例子如下所示

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)

返回碼處理的轉換如下:

pipe = os.popen(cmd, 'w')
...
rc = pipe.close()
if rc is not None and rc >> 8:
    print("There were some errors")
==>
process = Popen(cmd, stdin=PIPE)
...
process.stdin.close()
if process.wait() != 0:
    print("There were some errors")

替換 popen2 模組中的函式

注意

如果 popen2 函式的 cmd 引數是一個字串,則該命令透過 /bin/sh 執行。如果它是一個列表,則該命令直接執行。

(child_stdout, child_stdin) = popen2.popen2("somestring", bufsize, mode)
==>
p = Popen("somestring", shell=True, bufsize=bufsize,
          stdin=PIPE, stdout=PIPE, close_fds=True)
(child_stdout, child_stdin) = (p.stdout, p.stdin)
(child_stdout, child_stdin) = popen2.popen2(["mycmd", "myarg"], bufsize, mode)
==>
p = Popen(["mycmd", "myarg"], bufsize=bufsize,
          stdin=PIPE, stdout=PIPE, close_fds=True)
(child_stdout, child_stdin) = (p.stdout, p.stdin)

popen2.Popen3popen2.Popen4 的基本工作方式與 subprocess.Popen 相同,只是

  • 如果執行失敗,Popen 會丟擲異常。

  • capturestderr 引數被 stderr 引數替換。

  • 必須指定 stdin=PIPEstdout=PIPE

  • popen2 預設關閉所有檔案描述符,但是您必須使用 Popen 指定 close_fds=True,以保證在所有平臺或過去的 Python 版本上的這種行為。

舊版 Shell 呼叫函式

此模組還提供了來自 2.x commands 模組的以下舊版函式。這些操作隱式呼叫系統 shell,並且以上關於安全性和異常處理一致性的描述對這些函式無效。

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

返回在 shell 中執行 cmd(exitcode, output)

使用 Popen.check_output() 在 shell 中執行字串 cmd 並返回一個 2 元組 (exitcode, output)encodingerrors 用於解碼輸出;有關更多詳細資訊,請參閱關於 常用引數 的說明。

輸出中的尾部換行符會被刪除。命令的退出程式碼可以解釋為子程序的返回程式碼。示例

>>> 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, '')

可用性:Unix,Windows。

在 3.3.4 版本中更改: 增加了 Windows 支援。

該函式現在返回 (exitcode, output),而不是像 Python 3.3.3 及更早版本那樣返回 (status, output)。exitcode 的值與 returncode 的值相同。

在 3.11 版本中更改: 添加了 encodingerrors 引數。

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

返回在 shell 中執行 cmd 的輸出(stdout 和 stderr)。

類似於 getstatusoutput(),只是退出程式碼被忽略,返回值是一個包含命令輸出的字串。示例

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

可用性:Unix,Windows。

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

在 3.11 版本中更改: 添加了 encodingerrors 引數。

說明

在 Windows 上將引數序列轉換為字串

在 Windows 上,args 序列會被轉換為可以使用以下規則解析的字串(這與 MS C 執行時使用的規則相對應)

  1. 引數由空格分隔,空格可以是空格或製表符。

  2. 用雙引號括起來的字串被解釋為單個引數,而不管其中包含的空格如何。帶引號的字串可以嵌入到引數中。

  3. 前面有反斜槓的雙引號被解釋為字面雙引號。

  4. 反斜槓按字面解釋,除非它們緊鄰雙引號之前。

  5. 如果反斜槓緊鄰雙引號之前,則每對反斜槓被解釋為字面反斜槓。如果反斜槓的數量是奇數,則最後一個反斜槓將轉義下一個雙引號,如規則 3 中所述。

參見

shlex

提供解析和轉義命令列的模組。

停用 vfork()posix_spawn() 的使用

在 Linux 上,subprocess 預設情況下,在安全的情況下內部使用 vfork() 系統呼叫,而不是 fork()。這大大提高了效能。

如果您遇到需要阻止 Python 使用 vfork() 的極其不尋常的情況,可以將 subprocess._USE_VFORK 屬性設定為 false 值。

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

設定此值不會影響 posix_spawn() 的使用,它可能在其 libc 實現中內部使用 vfork()。如果需要阻止使用它,則有一個類似的 subprocess._USE_POSIX_SPAWN 屬性。

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

在任何 Python 版本上將它們設定為 false 都是安全的。當不支援時,它們對較舊的版本沒有影響。不要假設可以讀取這些屬性。儘管它們有名稱,但 true 值並不表示將使用相應的函式,而只是可能使用。

如果您必須使用這些私有旋鈕,請隨時提交問題,並提供重現您遇到的問題的方法。請在程式碼的註釋中連結到該問題。

在 3.8 版本中新增: _USE_POSIX_SPAWN

在 3.11 版本中新增: _USE_VFORK