2016-09-29 70 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() 

子进程结束之前,以确保没有错误的上升。