2009-05-19 172 views
4

說,我這樣寫:有沒有辦法輪詢從subprocess.Popen返回的文件句柄?

from subprocessing import Popen, STDOUT, PIPE 
p = Popen(["myproc"], stderr=STDOUT, stdout=PIPE) 

現在,如果我做

line = p.stdout.readline() 

我的程序等待,直到子輸出下一行。

有沒有什麼魔法可以對p.stdout這樣做,這樣我就可以讀取輸出,如果它在那裏,但只是繼續否則?我正在尋找像Queue.get_nowait()

我知道我可以創建一個線程閱讀p.stdout,但讓我們假設我不能創建新的線程。

回答

5

使用select模塊Python的標準庫,請參閱http://docs.python.org/library/select.htmlselect.select([p.stdout.fileno()], [], [], 0)立即返回一個元組,其項目是三個列表:如果在該文件描述符上有要讀取的內容,則第一個將是非空的。

8

使用p.stdout.read(1)這將由字符

讀取字符這裏是一個完整的例子:

import subprocess 
import sys 

process = subprocess.Popen(
    cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE 
) 

while True: 
    out = process.stdout.read(1) 
    if out == '' and process.poll() != None: 
     break 
    if out != '': 
     sys.stdout.write(out) 
     sys.stdout.flush() 
+0

謝謝!我不知道我見過多少個問題要求對這個問題做出簡單的回答 - 就是這樣。我一直試圖逐字閱讀字符,但我不知道如何檢查過程是否完成....完全錯過了poll() - 嗯。 +1 – jkp 2011-01-15 17:03:52

+1

+1此解決方案可能適用於Windows,其中`select`不適用於`subprocess`模塊創建的文件描述符。注意:如果子進程在stderr上產生足夠的輸出,那麼它可能會被阻塞,除非你從它讀取(OP將stderr重定向到stdout(`stderr = STDOUT`),所以這不會發生)。使用`is`與`None`比較,例如`如果x不是None:`。你可以使用`if out:`而不是`if out!='':`(它對於字節串和Unicode字符串都有效)。另外,如果`cmd`在非交互模式下使用塊緩衝,那麼在`cmd`刷新緩衝區之前`process.stdout`不會獲得任何東西。 – jfs 2013-04-03 07:26:07

相關問題