2012-11-11 55 views
2

我有一個簡單的Python程序:使用Python POPEN閱讀的最後一行

test.py:

import time 
for i in range(100000): 
    print i 
    time.sleep(0.5) 

我想用另一個程序,執行順序讀取最後的一個以上在上述程序正在計數的同時輸出線路。

import subprocess 

process = subprocess.Popen("test",stdout=PIPE) 
sleep(20) # sleeps an arbitrary time 
print stdout.readlines()[-1] 

問題是process.stdout.readlines()一直等到test.py結束執行。 有沒有什麼方法可以在程序執行時讀取輸出中寫入的最後一行?

+0

如果你的「試驗」方案還用Python編寫的,你應該考慮使用線程,並從一個側面傳遞信息給其他的,而不是打印和讀取文件。 .. – JBernardo

+0

@Jernardo感謝您的建議,但我即將嘗試實現的是讓它適用於任何程序。 –

回答

2

你可以使用collections.deque只保存行的最後一個指定號碼:

#!/usr/bin/env python 
import collections 
import subprocess 
import time 
import threading 

def read_output(process, append): 
    for line in iter(process.stdout.readline, ""): 
     append(line) 

def main(): 
    process = subprocess.Popen(["program"], stdout=subprocess.PIPE) 
    # save last `number_of_lines` lines of the process output 
    number_of_lines = 1 
    q = collections.deque(maxlen=number_of_lines) 
    t = threading.Thread(target=read_output, args=(process, q.append)) 
    t.daemon = True 
    t.start() 
    # 
    time.sleep(20) 

    # print saved lines 
    print ''.join(q), 
    # process is still running 
    # uncomment if you don't want to wait for the process to complete 
    ##process.terminate() # if it doesn't terminate; use process.kill() 
    process.wait() 

if __name__=="__main__": 
    main() 

other tail-like solutions that print only the portion of the output

See here如果你的孩子計劃使用塊緩衝(而不是線bufferring)爲其stdout在非交互式運行時運行。

+0

很好的答案,但可惜我有同樣的問題,我曾說過。它只顯示輸出,如果被調用的進程已經完成 –

+0

我相信'test.py' Python正在緩衝發送到'sys.stdout'的輸出。我通過使用'-u'標誌來解決這個問題:'python -u test.py'。 (否則輸出爲空。) – unutbu

+0

@unutbu給出錯誤IOError:[Errno 32]損壞的管道 –

0

相當瑣碎與sh.py

import sh 

def process_line(line): 
    print line 

process = sh.python("test.py", _out=process_line) 
process.wait()