2009-07-05 103 views
3

我想運行一個系統進程,攔截輸出,並在Python腳本中逐行修改它。從Python中的另一個進程實時攔截stdout

我最好的嘗試,它等待的過程中打印之前完成,方法是:

#!/usr/bin/env python 
import subprocess 

cmd = "waitsome.py" 
proc = subprocess.Popen(cmd, shell=True, bufsize=256, stdout=subprocess.PIPE) 
for line in proc.stdout: 
    print ">>> " + line.rstrip() 

腳本waitsome.py只是輸出線每隔半秒:

#!/usr/bin/env python 
import time 
from sys import stdout 

print "Starting" 
for i in range(0,20): 
    time.sleep(0.5) 
    print "Hello, iteration", i 
    stdout.flush() 

有一個簡單的解決方案得到subprocess允許實時迭代輸出?我必須使用線程嗎?

曾幾何時,我的腳本在Perl,這是小菜一碟:

open(CMD, "waitsome.py |"); 
while (<CMD>) { 
    print ">>> $_"; 
} 
close(CMD); 
+0

重複:http://stackoverflow.com/search?q=%5Bpython%5D+subprocess+real-time,具體http://stackoverflow.com/questions/527197/intercepting-stdout一個子進程,雖然它是運行,http://stackoverflow.com/questions/803265/getting-realtime-output-using-subprocess, – 2009-07-05 23:34:11

+0

對不起,我只看到第一個,並瞭解它是* subprocess'*緩衝的問題,而不是父python腳本的問題。 – 2009-07-06 02:13:45

回答

13

循環執行文件緩存不可避免地在相當大塊的東西 - 一個已知的問題與所有的Python 2。 *實現。它可以作爲你在Python 3.1打算,最終環路是稍有不同:

for line in proc.stdout: 
    print(">>> " + str(line.rstrip())) 

如果升級到Python 3.1是不現實的(!我知道這往往會),走另一條路,並編寫循環在老式的方式 - 迴路以下版本不工作,你在Python 2.打算*:

while True: 
    line = proc.stdout.readline() 
    if not line: 
     break 
    print ">>> " + line.rstrip() 
+0

這也適用於Python 3.0 – Stephan202 2009-07-06 01:55:43

0

這整個事情可以在一個迭代器封裝爲:

def subprocess_readlines(out): 
    while True: 
     line = out.readline() 
     if not line: 
      return 
     yield line 

和c alled爲:

for line in proc.stdout: 
    print ">>>", line.rstrip()