2009-02-26 122 views
3

有沒有辦法在Popen的同一個「會話」中進行多個調用?例如,我可以通過它調用一個調用,然後再調用另一個調用,而不必將這些命令連接成一個長字符串?Python持久性Popen

+2

由於「會話」在這種情況下並不意味着什麼,你能解釋一下你想做什麼嗎?這個問題很難解析,似乎也沒有多大意義。也許如果你解釋你的目標是什麼,這將有所幫助。 – 2009-02-26 11:43:06

回答

3

當您使用popen時,您不是「打電話」,而是運行可執行文件並通過stdin,stdout和stderr與它通話。如果可執行文件有某種方式進行工作的「會話」(例如,通過讀取stdin中的行),那麼是的,您可以執行此操作。否則,你需要多次執行。

subprocess.Popen是(大部分)只是圍繞execvp的包裝(3)

+0

這個解釋了實際的概念,而不是給出一個技術上正確的替代解決方案,這總是很好的。 – Arafangion 2009-02-26 06:50:09

0

例如,我可以通過它進行調用,然後再調用另一個調用,而不必將這些命令連接成一個長字符串?

聽起來就像你正在使用shell = True。不要,除非你需要。而是使用shell = False(默認值)並傳入命令/參數列表。

有沒有辦法在Popen的同一個「會話」中進行多個呼叫?例如,我可以通過它調用一個調用,然後再調用另一個調用,而不必將這些命令連接成一個長字符串?

任何原因你不能只是創建兩個Popen實例,並根據需要進行等待/溝通?如果我正確理解你的話,這是正常的做法。

+0

爲什麼不使用shell = True? – 2014-04-17 18:05:28

+0

@DavidDoria因爲它是一個安全責任 - 它允許代碼被注入,如果攻擊者可以影響對Popen的輸入。 (例如運行「ls」+ user_input顯然是錯誤的)。 shell = False乾淨地避免了這一切,因此安全屬性依賴於您在Popen中調用的程序,而沒有額外的東西。 – 2014-04-17 20:47:10

1

假設你希望能夠運行一個外殼,並將其發送多個命令(和讀取它們的輸出),看來你可以做是這樣的:

from subprocess import * 
p = Popen(['/bin/sh'], shell=False, stdin=PIPE, stdout=PIPE, stderr=PIPE) 

之後,例如,:

>>> p.stdin.write("cat /etc/motd\n") 
>>> p.stdout.readline() 
'Welcome to dev-linux.mongo.com.\n' 

(當然,你應該檢查stderr過,要不問Popen將其與stdout合併)。一個主要的問題與上面的是,stdinstdout管道處於阻塞模式,所以很容易從殼中輸出「卡住」等待。儘管我還沒有嘗試過,但ActiveState網站上有一個recipe,顯示瞭如何解決這個問題。

更新:看相關的問題/回答後,它看起來可能比較簡單,只需使用Python的內置select模塊,看看是否有數據就stdout閱讀(你也應該做同樣的當然),例如:

>>> select.select([p.stdout], [], [], 0) 
([<open file '<fdopen>', mode 'rb' at 0x10341690>], [], [])