7 Stimmen

warum kehrt subprocess.Popen(...) nicht immer zurück?

Ich hoffe, dies ist eine einfache Python-Frage.

Wenn ich das Folgende im Python-Interpreter versuche:

>>> import process
>>> def test(cmd):
...   p = subprocess.Popen(cmd)
...
>>> test(['ls', '-l'])

Es wird die ls -l , aber ich muss "Return" drücken, um eine neue >>> Eingabeaufforderung zu erhalten.

Wenn ich jedoch das Folgende versuche:

>>> import process
>>> def test(cmd):
...   p = subprocess.Popen(cmd)
...   p.wait()
...
>>> test(['ls', '-l'])

Dann wird die ls -l wird mit einer sofortigen >>>-Eingabeaufforderung ausgeführt.

Eine weitere Variante:

>>> import process
>>> def test(cmd):
...   p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
...
>>> test(['ls', '-l'])

Dadurch erhalte ich sofort eine neue Eingabeaufforderung.

Das letzte Beispiel kommt dem, was ich will, am nächsten. Mein Ziel ist es, einen Kindprozess zu starten, auf dessen Beendigung zu warten und dann dessen stdout in meinem Elternprozess zu verwenden, indem ich mich auf p.stdout während stderr einfach dorthin gedruckt wird, wo es sonst auch gedruckt würde.

Im Moment bleibt die letzte Version in meiner aktuellen Anwendung einfach hängen: p = subprocess.Popen(cmd, stdout=subprocess.PIPE) mit oder ohne p.wait() .

Danke,

Charlie

8voto

dF. Punkte 70587

In der ersten Variante, test() kehrt unmittelbar nach dem Starten des Prozesses zurück, aber bevor seine Ausgabe an die Konsole gesendet wird.

Wenn Sie sich die Ausgabe ansehen, können Sie hacer erhalten Sie die Eingabeaufforderung, unmittelbar vor der Ausgabe von ls .

>>> test(['ls', '-l'])
>>> total 0                            <----- test() returns, new propmpt
--rw-r--r--    1 foo bar   7 Mar 24 17:38
etc etc

In der zweiten Variante, test() wartet auf die Beendigung des Prozesses, bevor es zurückkehrt.

In der dritten Version haben Sie Recht, dass Sie möglicherweise aus dem Kindprozess lesen müssen stdout damit sie fortgesetzt werden kann.

7voto

Vielleicht habe ich meine eigene Frage beantwortet. Ich glaube, dass ich im letzten Fall explizit von p.stdout lesen muss, damit mein Prozess fortgesetzt werden kann.

d. h:

p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
output = p.stdout.readlines()
....

Danke an alle

0voto

user3273866 Punkte 554

Verwenden Sie einfach die Methode communicate(), die nicht zurückgegeben werden muss.

>>> test(['ls', '-l'])
>>> 
>>> def test(cmd):
...    p = subprocess.Popen(cmd).communicate()
... 
>>> test(['ls', '-l'])

0voto

storm_m2138 Punkte 2045

Hier ist ein Befehl, der Google ewig anpingt, so dass er manuell beendet werden muss, um die Ausgabe abzurufen.

Siehe die Teilprozessdokumentation für Anweisungen zur Umwandlung von os.popen()-Methodenaufrufen in vollständige subprocess.Popen-Klassen.

host = "www.google.com"
command = "ping %s -t"%host

#p = os.popen(command) -- using Popen instead of os.popen() to allow calling terminate()
p = Popen(command, stdout=subprocess.PIPE)

time.sleep(5)
print "term"
p.terminate()
pingResultSoFar = p.communicate()[0] # get what has been printed to standard out so far
print pingResultSoFar

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X