python-subprocess: Lesen-Ausgabe von Teilprozess
Ich habe folgenden Skript:
#!/usr/bin/python
while True:
x = raw_input()
print x[::-1]
Rufe ich es aus ipython
:
In [5]: p = Popen('./script.py', stdin=PIPE)
In [6]: p.stdin.write('abc\n')
cba
und es funktioniert gut.
Jedoch, wenn ich dies tun:
In [7]: p = Popen('./script.py', stdin=PIPE, stdout=PIPE)
In [8]: p.stdin.write('abc\n')
In [9]: p.stdout.read()
den Dolmetscher hängt. Was mache ich falsch? Ich möchte in der Lage sein, sowohl das schreiben als auch das Lesen aus einem anderen Prozess mehrere Male, um einige Aufgaben zu diesem Prozess. Was muss ich anders machen?
BEARBEITEN 1
Wenn ich communicate
, bekomme ich diese:
In [7]: p = Popen('./script.py', stdin=PIPE, stdout=PIPE)
In [8]: p.communicate('abc\n')
Traceback (most recent call last):
File "./script.py", line 4, in <module>
x = raw_input()
EOFError: EOF when reading a line
Out[8]: ('cba\n', None)
EDIT 2
Ich versuchte Spülung:
#!/usr/bin/python
import sys
while True:
x = raw_input()
print x[::-1]
sys.stdout.flush()
und hier:
In [5]: from subprocess import PIPE, Popen
In [6]: p = Popen('./script.py', stdin=PIPE, stdout=PIPE)
In [7]: p.stdin.write('abc')
In [8]: p.stdin.flush()
In [9]: p.stdout.read()
aber es hängt wieder.
InformationsquelleAutor gruszczy | 2010-09-27
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich glaube, es gibt zwei Probleme bei der Arbeit hier:
1) Ihre parent-Skript ruft
p.stdout.read()
, die alle Daten gelesen, bis das Ende der Datei. Jedoch, Ihr Kind-Skript läuft in einer Endlosschleife, so dass end-of-file wird nie passieren. Wahrscheinlich wollen Siep.stdout.readline()
?2) Im interaktiven Modus werden die meisten Programme tun Puffer nur eine Zeile zu einem Zeitpunkt. Wenn Sie von einem anderen Programm, Sie Puffer vieles mehr. Die Pufferung verbessert die Effizienz in vielen Fällen verursacht aber Probleme, wenn zwei Programme brauchen um interaktiv zu kommunizieren.
Nach
p.stdin.write('abc\n')
hinzufügen:In Ihrem Teilprozess Skript, nach
print x[::-1]
fügen Sie den folgenden innerhalb der Schleife:(und
import sys
oben)Vielen Dank für das update. Ich habe aktualisiert mein Antwort-Adresse ein anderes problem.
Hinzufügen
sys.stdout.flush()
auf das Skript und mitp.stdout.readline
schließlich geholfen. Vielen Dank für Eure Hilfe.Danke Daniel Statzbash, dafür, dass mein Leben leichter. (Spülung auch nach dem schreiben von "\n")
InformationsquelleAutor Daniel Stutzbach
Den Teilprozess Methode check_output kann nützlich sein, für diese:
output = subprocess.check_output('./script.py')
- Und Ausgabe stdout aus dem Prozess. Wenn Sie brauchen, stderr, zu:
output = subprocess.check_output('./script.py', stderr=subprocess.STDOUT)
Weil Sie vermeiden verwalten Rohre direkt, kann es umgehen, ist Ihr Problem.
InformationsquelleAutor JoshD
Wenn Sie möchten, Durchlaufen Sie mehrere Linien zu
script.py
dann müssen Sie Lesen/schreiben gleichzeitig:Ausgabe:
Wo
script.py
:Oder
Oder
href="http://docs.python.org/reference/simple_stmts.html#grammar-token-print_stmt" >"drucken " chevron" ähnlich wie
print(s, file=p.stdin)
, die verfügbar ist, nachdemfrom __future__ import print_function
.InformationsquelleAutor jfs
Sind Sie wahrscheinlich stolpern über Python die Ausgabe-Pufferung. Hier ist, was
python --help
zu sagen hat über es.Ausgabe an Leitungen gepuffert ist aus performance-Gründen. (Flushing line-by-line ist sehr ineffizient, aber Sie bemerken nicht, wenn das Programm verbringt die meiste Zeit mit dem warten auf die Nutzer) Bei der Spülung von Rohrleitungen, die Pufferung verbessert die Leistung erheblich, entweder die Verbesserung der Laufzeiten oder eine Verringerung der CPU-Last, je nachdem, wie I/O-gebunden sind, ist die Bedienung.
Als für das leeren der Puffer programmgesteuert, könnten Sie versuchen
sys.stdout.flush()
im Kind-Prozess, aber ich habe es nie benutzt und es ist nicht wirklich gute Architektur zu verwenden, die es in dieser Art und Weise. (Es ist mehr für den Einsatz als Teil des "sync to disk" - Prozess in concert mitos.fsync
) Besser, wenn der übergeordnete Prozess Pufferung deaktivieren, wie erforderlich, entweder über-u
oder diePYTHONUNBUFFERED
Umgebungsvariable.InformationsquelleAutor ssokolow
Wenn Sie sich durch schreiben p.stdin, schließen Sie:
p.stdin.close()
InformationsquelleAutor Thud Foo
Verwenden
communicate()
statt.stdout.read()
.Beispiel:
Diese Empfehlung kommt von der Popen Objekte Abschnitt in der Teilprozess Dokumentation:
Er kommunizieren möchte, mehrere Male mit dem Teilprozess.
communicate
kann das nicht tun.InformationsquelleAutor David Narayan