2009-07-26 3 views
20

Ich versuche, von einem Prozess zu lesen, der lange und zeitraubende Ausgabe produziert. Ich möchte jedoch die Ausgabe abfangen, wenn produziert wird. Aber mit so etwas wie das folgende erscheint die Ausgabe des Befehls Pufferung zu sein, so dass ich am Ende der Ausgangsleitungen immer alle auf einmal:Unbuffered lesen von Prozess mit Subprozess in Python

p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, bufsize=0) 
    for line in p.stdout: 
     print line 

ich versuche dies auf MacOS 10.5

+0

Duplizieren: http://stackoverflow.com/questions/874815/how-do-i-get-real-time-information-back-from -a-subprozess-popen-in-python-2-5, http://stackoverflow.com/questions/527197/intercepting-stdout-of-a-subprocess-while-it-is-running –

Antwort

28

Die Datei Iterator tut einig interne Pufferung on its own. Versuchen Sie folgendes:

line = p.stdout.readline() 
while line: 
    print line 
    line = p.stdout.readline() 
+0

Funktioniert gut. Vielen Dank! – Abhi

+0

Danke, du hast mir Haarzöpfe gerettet. – haridsv

6

Normalerweise wird jedes Programm mehr Pufferung tun an seinem Eingang und/oder Ausgangskanäle, als Sie zu wünschen erscheinen ... es sei denn, es zum Narren gehalten hat, zu glauben, der Kanal ist eigentlich ein Terminal!

Verwenden Sie für diesen "Zweck für einen guten Zweck" pexpect - es funktioniert gut auf einem Mac (das Leben ist härter unter Windows, obwohl es Lösungen gibt, die sogar dort helfen können - zum Glück brauchen wir nicht Bleiben Sie bei denen, während Sie stattdessen einen Mac verwenden).

3

Dies war eigentlich ein Fehler, der in Python 2.6 festgelegt ist: http://bugs.python.org/issue3907

+4

Auf Python 2.7 'für Zeile in p.stdout' verzögert noch seine Ausgabe, während' für Zeile in iter (p.stdout.readline, b '') 'wie erwartet funktioniert (es produziert Zeilen, sobald sie verfügbar sind). – jfs

+0

Sorry, 2.x wird die neue io-Bibliothek standardmäßig nicht verwenden, wie der letzte Kommentar zum Fehlerbericht sagt; Sie müssten etwas wie 'für Zeile in io.open (p.stdin.fileno())' tun. – Ari

+1

@Ari: Sollte das für Zeile in io.open (p.stdout.fileno()) 'sein? –