2016-09-29 72 views
-1

我使用subprocess.Popen創建了一個流程並獲得其stdout。 我想從stdout中讀取內容並在另一個線程中打印出來。 因爲我以後的目的是製作一個交互式程序,所以我不能使用subprocess.communicate如何在Python中讀取子流程的流?

我的基本要求是:一旦子進程輸出了一些東西,線程應該立即將它打印出來到屏幕上。

下面是代碼之間的「開始」和「結束」應該是非常快的

import subprocess 
import thread 
import time 

def helper(s): 
    print "start",time.gmtime() 
    while True: 
     print "here" 
     print s.next() 
    print "finished",time.gmtime() 
    thread.start_new_thread(helper,(out_stream,)) 

def process_main(): 
    global stdin_main 
    global stdout_main 
    p = subprocess.Popen("/bin/bash", shell=False, stdin=subprocess.PIPE, 
         stdout=subprocess.PIPE, 
         stderr=subprocess.STDOUT, bufsize=0) 
    stdin_main = p.stdin 
    stdout_main = p.stdout 
    th1 = thread_print_stream(stdout_main) 
    stdin_main.write("ls -la\n") 
    stdin_main.flush() 
    time.sleep(30) 

    p.terminate() 

process_main() 

時間的流逝。然而,它與進程終止前的時間完全相同,爲30秒。 我不明白爲什麼輸出不是實例。 或者我該如何做到這一點?

+0

您可能正在遭受緩衝。這可能會有所幫助:http://stackoverflow.com/questions/1183643/unbuffered-read-from-process-using-subprocess-in-python – cdarke

+0

@cdarke患有子進程或文件?我已經設置了bufsize = 0。 – worldterminator

+0

您是否閱讀過鏈接中接受的答案? – cdarke

回答

0

正如cdarke提到的那樣。這個程序遭受緩衝。但它更像是Python 2.x中的一個bug。 當前程序中的邏輯沒有錯。

要解決此問題,您必須重新打開stdout。 像下面的代碼:

def thread_print_stream(out_stream): 
    def helper(s): 
    print "start",time.gmtime() 
    for line in io.open(out_stream.fileno()): 
     print line 
    print "finished",time.gmtime() 
    thread.start_new_thread(helper,(out_stream,)) 

並添加

stdin_main.close() 
stdout_main.close() 

子進程結束之前,以確保沒有錯誤的上升。