2013-12-10 26 views
2

我需要從腳本運行子進程。子進程是一個交互式(shell-like)應用程序,我通過子進程'stdin發出命令。
我發出命令後,子進程輸出結果到stdout,然後等待下一個命令(但不終止)。等待來自不終止的子進程的輸出

例如:

from subprocess import Popen, PIPE 
p = Popen(args = [...], stdin = PIPE, stdout = PIPE, stderr = PIPE, shell = False) 
# Issue a command: 
p.stdin.write('command\n') 
# *** HERE: get the result from p.stdout *** 
# CONTINUE with the rest of the script once there is not more data in p.stdout 
# NOTE that the subprocess is still running and waiting for the next command 
# through stdin. 

我的問題正從p.stdout結果。當p.stdout中有新數據時,腳本需要獲取輸出;但一旦沒有更多的數據,我想繼續使用腳本。
子進程沒有終止,所以我不能使用communicate()(它等待進程終止)。
我試着發出命令,這樣之後,從p.stdout閱讀:

res = p.stdout.read() 

但子進程不夠快,而我只是得到空的結果。
我想了解一下循環中的投票p.stdout,直到我得到一些東西,但是我怎麼知道我得到了一切?無論如何,這看起來很浪費。

有什麼建議嗎?

+0

嘗試使用異步librry /框架,如電路(例如:https://bitbucket.org/circuits/circuits-dev/src/tip/examples/ping.py) –

+0

@詹姆斯米爾斯,去異步可以工作,但我認爲這會使我想要做的事複雜化。如果沒有其他解決方案出現,我會這樣做。謝謝。 – EyalAr

+0

唯一的另一種方法是使用線程來隱藏阻塞呼叫。任何選項都會涉及某種併發/異步庫/框架。你可以使用一個:) –

回答

0

調查幾種選擇之後,我得出兩個解決方案:

  1. 設置子標準輸出流通過fcntl模塊是不可阻擋。
  2. 使用線程將子進程的輸出收集到代理隊列,然後從主線程讀取隊列。

我在this post中描述了兩種解決方案(以及問題及其起源)。

0

在gevent-1.0中使用gevent.subprocess來替代標準subprocess模塊。它可以使用同步邏輯完成併發任務,並且不會阻塞腳本。這裏是關於gevent.subprocess的簡短教程

+0

我的問題不是併發性和同步性。我澄清了這個問題。謝謝。 – EyalAr