2017-01-16 91 views
2

似乎都執行一個子進程,並創建一個管道進行/輸出,只是子進程更新。Python:什麼時候應該使用subprocess.Popen而不是os.popen?

我的問題是,subprocess.Popen可以做什麼,而os.popen不能,所以我們需要一個新的子進程?

爲什麼python語言沒有選擇增強os.popen,但創建了一個新模塊?

感謝

+4

從https://docs.python.org/2/library/os.html#os.popen「自2.6版棄用:此功能已過時,使用'subprocess'模塊。」 –

+2

請參閱https://www.python。org/dev/peps/pep-0324 /動機與理論部分:防範某些安全風險,跨進程異常,使用文件描述符更好的操作等。 –

+1

除了安全性和可靠性問題,恕我直言,老'os。波潘家族很麻煩,令人困惑。在編寫代碼時,如果沒有密切提及文檔,幾乎不可能正確使用。相比之下,'subprocess'是天賜之物,儘管在使用文檔時參考文檔仍然是明智之舉。 ;) –

回答

6

簡短的回答:切勿使用os.popen,總是使用subprocess

你可以從Python 2.7 os.popen docs看到:

自2.6版本不推薦使用:此功能已經過時了。使用 subprocess模塊。特別檢查Replacing Older Functions with the subprocess Module部分。

舊功能家族存在各種限制和問題。正如文檔中提到的那樣,2.6之前的版本在Windows上甚至不可靠。

背後subprocess的動機是PEP 324 -- subprocess - New process module解釋說:

動機

開始新的進程是任何編程語言, 一個共同的任務,並在像Python的高級語言很常見。良好的支持 需要這個任務,因爲:

  • 啓動過程可能意味着 安全風險不合適的功能:如果程序是通過shell啓動,並 參數包含shell元字符,結果可能是 災難性的。 [1]

  • 它使Python成爲 過度複雜的shell腳本的更好替代語言。

目前,Python有 進程創建的大量不同的功能。這使開發人員很難選擇。

的子模塊提供了以下增強功能比以前 功能:

  • 一個「統一」模塊提供了從以前的 功能的全部功能。

  • 跨進程異常:在新進程開始執行之前發生在子進程 中的異常在父進程 中重新提出。這意味着,例如,處理exec() 故障很容易。例如,對於popen2,如果執行失敗,則無法檢測到 。

  • 用於在fork和exec之間執行自定義代碼的鉤子。這個 可以用於,例如,改變uid。

  • 沒有隱式調用/ bin/sh。這意味着不需要 來逃離危險的shell元字符。

  • 文件描述符重定向的所有組合都是可能的。例如,「python-dialog」[2]需要產生一個進程 並重定向stderr,但不是stdout。目前的功能無法使用臨時文件,這是不可能的。

  • 隨着子模塊,它可以控制,如果之前的新方案是執行 所有打開的 文件描述符應該被關閉。

  • 支持連接多個子進程(shell「管道」)。

  • 通用換行支持。

  • 一個通信()方法,它可以很容易地發送標準輸入數據 並讀取標準輸出和標準錯誤數據,而沒有死鎖風險。大多數人都知道 子進程通信中涉及的流量控制問題,但並非所有人都有耐心或 技能來編寫完全正確且無死鎖的選擇循環。這意味着許多Python應用程序包含種族 條件。標準庫 中的communications()方法解決了這個問題。

請參閱PEP鏈接的基本原理,以及進一步的細節。

除了安全&可靠性問題,恕我直言,舊的os.popen家庭是麻煩和混亂。在編寫代碼時,如果沒有密切提及文檔,幾乎不可能正確使用。相比之下,subprocess是天賜之物,但在使用文檔時參考文檔仍然是明智之舉。 ;)

偶爾會有人看到人們建議在Python 2.7中使用os.popen而不是subprocess.Popen,例如Python subprocess vs os.popen overhead,因爲速度更快。當然,速度更快,但是這是因爲它不會做各種事情,這對保證它的安全運行至關重要!


FWIW,os.popen itself still exists in Python 3,但它的安全通過subprocess.Popen實現的,所以你可能也只是使用subprocess.Popen直接自己。 os.popen系列的其他成員不再存在於Python 3中.功能家族仍然存在於Python 3中,但文檔建議使用由subprocess模塊提供的更強大的功能。

相關問題