Echtzeit-Teilprozess.Popen, die über stdout und PIPE
Ich versuche zu greifen stdout
aus einer subprocess.Popen
Anruf und ich bin zwar erreichen dies problemlos tun:
cmd = subprocess.Popen('ls -l', shell=True, stdout=PIPE)
for line in cmd.stdout.readlines():
print line
Ich würde gerne zu greifen stdout
in "Echtzeit". Mit der oben beschriebenen Methode, ROHR, der darauf wartet, greifen Sie alle stdout
- und dann kehrt er zurück.
Also für logging-Zwecke, diese nicht erfüllen meine Anforderungen (z.B. "sehen", was Los ist, während es geschieht).
Gibt es einen Weg, um Zeile für Zeile, stdout
während Sie ausgeführt wird? Oder ist dies eine Einschränkung der subprocess
(warten zu müssen, bis die PIPE
schließt).
BEARBEITEN
Wenn ich wechseln readlines()
für readline()
bekomme ich nur die Letzte Zeile der stdout
(nicht ideal):
In [75]: cmd = Popen('ls -l', shell=True, stdout=PIPE)
In [76]: for i in cmd.stdout.readline(): print i
....:
t
o
t
a
l
1
0
4
InformationsquelleAutor der Frage alfredodeza | 2010-01-17
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ihre Dolmetscherin ist die Pufferung. Fügen Sie einen Aufruf sys.stdout.flush() nach Ihrer print-Anweisung.
InformationsquelleAutor der Antwort Jeff
Tatsächlich, die wirkliche Lösung ist die direkte Umleitung des stdout des Teilprozess des stdout des Prozesses.
In der Tat, mit deiner Lösung, Sie können nur drucken, stdout, nicht stderr, zum Beispiel, zur gleichen Zeit.
Den
communicate()
ist, so zu machen der Aufruf blockiert bis zum Ende des teilprozesses, sonst würde es direkt gehen, um die nächste Zeile und das Programm möglicherweise beenden, bevor Sie den Teilprozess (obwohl die Umleitung auf Ihre stdout wird immer noch funktionieren, selbst nachdem Sie Ihre python-Skript geschlossen hat, habe ich es getestet).So, zum Beispiel, den Sie umleiten sowohl stdout und stderr, und in absoluter Echtzeit.
Beispielsweise in meinem Fall, die ich getestet habe mit diesem script
slow_cmd_output.sh
:InformationsquelleAutor der Antwort Undo
Bekommen Ausgabe "in Echtzeit",
subprocess
ist ungeeignet, da Sie nicht besiegen kann der andere Prozess die Pufferung Strategien. Das ist der Grund, warum ich immer empfehlen, wenn eine solche "Echtzeit" - Ausgabe greifen gewünscht ist (ganz eine häufige Frage auf stack overflow!), stattdessen verwenden pexpect (überall, aber Windows -- Windows, wexpect).InformationsquelleAutor der Antwort Alex Martelli
Drop die readlines() die Koaleszenz der Ausgabe.
Auch Sie müssen zur Durchsetzung der Linie der Pufferung da die meisten Befehle, da er intern Puffer Ausgabe in eine pipe. Für details siehe: http://www.pixelbeat.org/programming/stdio_buffering/
InformationsquelleAutor der Antwort pixelbeat
Als dies ist eine Frage, die ich suchte nach einer Antwort zu Tage, ich wollte das hier für diejenigen, die Folgen. Während es wahr ist, dass
subprocess
nicht bekämpfen, der andere Prozess ist die Pufferung Strategie, in dem Fall, wo Sie anrufen, eine andere Python-Skript mitsubprocess.Popen
KÖNNEN Sie sagen, dass es zu Beginn einer ungepufferten python.Ich habe auch Fälle gesehen, wo die popen Argumente
bufsize=1
unduniversal_newlines=True
geholfen haben, mit der Enthüllung der verstecktenstdout
.InformationsquelleAutor der Antwort ochawkeye
InformationsquelleAutor der Antwort
Den Aufruf
readlines
wartet auf den Prozess zu beenden. Ersetzen Sie diese mit einer Schleife umcmd.stdout.readline()
(Hinweis im singular) und alles sollte gut sein.InformationsquelleAutor der Antwort Jakob Borg
Wie bereits dargelegt, das Problem ist in der stdio-Bibliothek Pufferung der wie printf-Anweisungen, wenn kein Endgerät angeschlossen ist, um den Prozess. Es ist ein Weg, um dies auf der Windows-Plattform sowieso. Möglicherweise gibt es eine ähnliche Lösung auch auf anderen Plattformen.
Unter Windows können Sie erzwingen, erstellen Sie eine neue Konsole bei der prozesserstellung. Das gute ist, das kann verborgen bleiben, so dass Sie nie sehen (dies geschieht durch shell=True innerhalb der Teilprozess-Modul).
oder
Eine etwas umfassendere Lösung ist, dass Sie explizit den Wert der STARTUPINFO-params die verhindert, dass die Einführung eines neuen und unnötigen cmd.exe shell-Prozess die shell=True haben.
InformationsquelleAutor der Antwort Chris