2016-09-29 2 views
-1

Ich erstelle einen Prozess mit subprocess.Popen und erhalte seinen stdout. Ich möchte Inhalt von stdout lesen und es in einem anderen Thread ausdrucken. Da es mein Ziel ist, später ein interaktives Programm zu erstellen, kann ich subprocess.communicate nicht verwenden.Wie liest man den Stream eines Subprozesses in Python?

Meine Grundvoraussetzung ist: Sobald der Subprozess etwas ausgegeben hat, sollte der Thread ihn sofort auf den Bildschirm ausgeben.

Hier ist der Code

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() 

Zeit verstreichen zwischen "Start" und "fertig" sollte sehr schnell sein. Es sind jedoch 30 Sekunden, was genau der Zeit entspricht, bevor der Prozess beendet wurde. Ich kann nicht verstehen, warum die Ausgabe keine Instanz ist. Oder wie kann ich es instanziell machen?

+0

Sie leiden wahrscheinlich unter Pufferung. Dies könnte helfen: http://stackoverflow.com/questions/1183643/unbuffered-read-from-process-using-subprocess-in-python – cdarke

+0

@cdarke leidet unter Unterprozess oder Datei? Ich habe bufsize = 0 gesetzt. – worldterminator

+0

Haben Sie die akzeptierte Antwort im Link gelesen? – cdarke

Antwort

0

Wie cdarke erwähnt. Dieses Programm leidet unter Pufferung. Allerdings ist es eher ein Fehler in Python 2.x. Die Logik ist im aktuellen Programm nichts falsch.

Um das Problem zu beheben, müssen Sie das stdout erneut öffnen. Wie der folgenden Code:

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,)) 

Und füge

stdin_main.close() 
stdout_main.close() 

vor subprocess beendet, sicher keinen Fehler ansteigen zu lassen.

Verwandte Themen