Python 模塊 subprocess 派生新進程

Python 模塊 subprocess 派生新進程

Python 使用模塊 subproces,生成新的進程並與之通信。

在 Python 2中,提供了 call(),check_call() 和 check_output()函數生成新進程的 API,他們也被帶到了 Python 3。在 Python 3 中,新增了高級函數 run(),能夠生成新進程並收集輸出。

Popen 提供了低級別的 API,可以接收參數,父進程能夠和子進程通過管道(Pipe)通信,它的接口 API 和高級的接口 API 保持一致,並且內部能夠保證資源得到清理,例如自動關閉管道和文件描述符。

模塊 subprocess 是用來替代舊的 os 模塊函數,例如 os.system(),os.spawnv()。

雖然 Windows 和 Unix 的底層進程模型是不一樣的,但是接口 API 保持了一致,代碼在多個平臺不需要做太多的改動。

運行外部命令


使用 run() 函數運行外部的命令。

Python 模塊 subprocess 派生新進程

執行:

Python 模塊 subprocess 派生新進程

run() 函數的第一個參數是一個字符串列表,這樣可以避免被 shell 解析特殊的字符。返回一個 CompletedProcess 實例,包含輸出的信息或者退出狀態。

使用屬性 shell 設置為 True,會讓 subprocess 生成一個新 shell 進程,然後再運行命令,此時第一個參數需要傳遞一個字符串。

Python 模塊 subprocess 派生新進程

執行:

Python 模塊 subprocess 派生新進程

call() 函數返回子進程的退出狀態,相當於不傳給 run() 參數 check=True

錯誤處理


設置屬性 check 為 True,如果命令執行發生錯誤,會觸發異常 CalledProcessError。

Python 模塊 subprocess 派生新進程

執行:

Python 模塊 subprocess 派生新進程

當給 run() 屬性 check 設置為 True,相當於調用 check_call() 函數

捕獲輸出


上例中,執行 run() 函數,默認都把子進程的輸出打印了,這是因為子進程的輸入輸出通道和父進程的一致。為了捕獲輸出或者錯誤信息,需要傳遞屬性 stdout 或者 stderr,設置為 subprocess.PIPE。

Python 模塊 subprocess 派生新進程

執行:

Python 模塊 subprocess 派生新進程

當調用 run() 時,check=True 而且 stdout=PIPE ,相當於調用 check_output() 函數

為了捕獲錯誤消息,我們可以把標準錯誤重定向到標準輸出,設置屬性 stderr 為 STDOUT。

Python 模塊 subprocess 派生新進程

執行:

Python 模塊 subprocess 派生新進程

上例中,使用 shell 命令輸出兩個字符串,一個是標準輸出,另一個把標準輸出重定向到標準錯誤。因為設置了屬性 stderr,最終兩個字符串都返回了。

抑制輸出


設置 stdout 為 DEVNULL 抑制輸出數據,下面的例子抑制了標準輸出流和標準錯誤流。

Python 模塊 subprocess 派生新進程

執行:

Python 模塊 subprocess 派生新進程

使用 Popen


實例化 Popen, 並且設置 stdout 為 PIPE,調用 communicate() 方法捕獲輸出。

Python 模塊 subprocess 派生新進程

執行:

Python 模塊 subprocess 派生新進程

設置參數 stdin 為 PIPE,然後調用 communicate() 方法可以向子進程傳遞數據。

Python 模塊 subprocess 派生新進程

執行:

Python 模塊 subprocess 派生新進程

同時設置 stdin 和 stdout 為 PIPE,能夠和子進程雙向讀取和寫入數據。

Python 模塊 subprocess 派生新進程

執行:

Python 模塊 subprocess 派生新進程

通過設置 stdout 和 stderr,同時捕獲輸出和錯誤。

Python 模塊 subprocess 派生新進程

執行:

Python 模塊 subprocess 派生新進程


分享到:


相關文章: