Ich muss einen Shell-Befehl asynchron über ein Python-Skript ausführen. Damit meine ich, dass mein Python-Skript weiterhin ausgeführt werden soll, während der externe Befehl ausgeht und alles tut, was er tun muss.
Ich habe diesen Beitrag gelesen:
Ich habe dann einige Tests durchgeführt, und es sieht so aus, os.system()
als würde ich den Job erledigen, vorausgesetzt, ich verwende ihn &
am Ende des Befehls, damit ich nicht warten muss, bis er zurückkommt. Ich frage mich, ob dies der richtige Weg ist, um so etwas zu erreichen. Ich habe es versucht, commands.call()
aber es wird bei mir nicht funktionieren, da es den externen Befehl blockiert.
Bitte lassen Sie mich wissen, ob eine Verwendung os.system()
hierfür ratsam ist oder ob ich eine andere Route ausprobieren sollte.
quelle
Wenn Sie viele Prozesse parallel ausführen und dann verarbeiten möchten, wenn sie zu Ergebnissen führen, können Sie die Abfrage wie folgt verwenden:
Der Kontrollfluss dort ist etwas kompliziert, weil ich versuche, ihn klein zu machen - Sie können ihn nach Ihrem Geschmack umgestalten. :-)
Dies hat den Vorteil, dass die Anforderungen für die frühzeitige Fertigstellung zuerst bearbeitet werden. Wenn Sie
communicate
den ersten laufenden Prozess aufrufen und sich herausstellt, dass dieser am längsten läuft, haben die anderen laufenden Prozesse dort im Leerlauf gesessen, als Sie ihre Ergebnisse hätten verarbeiten können.quelle
os.waitpid
direkt verwenden, um zu überprüfen, ob ein untergeordneter Prozess seinen Status geändert hat.['/usr/bin/my_cmd', '-i', path]
anstelle von['/usr/bin/my_cmd', '-i %s' % path]
Ich frage mich, ob dieses [os.system ()] der richtige Weg ist, um so etwas zu erreichen.
Nein
os.system()
ist nicht der richtige Weg. Deshalb sagt jeder zu verwendensubprocess
.Weitere Informationen finden Sie unter http://docs.python.org/library/os.html#os.system
quelle
Ich habe gute Erfolge mit dem asyncproc- Modul erzielt , das sich gut mit der Ausgabe der Prozesse befasst. Beispielsweise:
quelle
Die Verwendung von pexpect mit nicht blockierenden Readlines ist eine weitere Möglichkeit, dies zu tun. Pexpect löst die Deadlock-Probleme, ermöglicht das einfache Ausführen der Prozesse im Hintergrund und bietet einfache Möglichkeiten für Rückrufe, wenn Ihr Prozess vordefinierte Zeichenfolgen ausspuckt, und erleichtert im Allgemeinen die Interaktion mit dem Prozess erheblich.
quelle
In Anbetracht von "Ich muss nicht warten, bis es zurückkommt" ist eine der einfachsten Lösungen folgende:
Aber ... Nach dem, was ich gelesen habe, ist dies aufgrund der Sicherheitsrisiken von nicht "der richtige Weg, um so etwas zu erreichen"
subprocess.CREATE_NEW_CONSOLE
Flagge verursachten .Die wichtigsten Dinge, die hier passieren, sind die
subprocess.CREATE_NEW_CONSOLE
Erstellung einer neuen Konsole und.pid
(gibt die Prozess-ID zurück, damit Sie das Programm später überprüfen können, wenn Sie möchten), damit Sie nicht warten müssen, bis das Programm seinen Job beendet hat.quelle
Ich habe das gleiche Problem beim Versuch, mit der S3270-Skriptsoftware in Python eine Verbindung zu einem 3270-Terminal herzustellen. Jetzt löse ich das Problem mit einer Unterklasse von Process, die ich hier gefunden habe:
http://code.activestate.com/recipes/440554/
Und hier ist das Beispiel aus der Datei:
quelle
Die akzeptierte Antwort ist sehr alt.
Ich habe hier eine bessere moderne Antwort gefunden:
https://kevinmccarthy.org/2016/07/25/streaming-subprocess-stdin-and-stdout-with-asyncio-in-python/
und einige Änderungen vorgenommen:
Es ist unwahrscheinlich, dass die Beispielbefehle auf Ihrem System einwandfrei funktionieren, und es werden keine seltsamen Fehler behandelt. Dieser Code zeigt jedoch eine Möglichkeit, mehrere Unterprozesse mit Asyncio auszuführen und die Ausgabe zu streamen.
quelle
wait()
direkte Übergeben von Coroutine-Objekten ist veraltetHier gibt es mehrere Antworten, aber keine davon hat meine folgenden Anforderungen erfüllt:
Ich möchte nicht warten, bis der Befehl beendet ist, oder mein Terminal mit Unterprozessausgaben verschmutzen.
Ich möchte ein Bash-Skript mit Weiterleitungen ausführen.
Ich möchte Piping in meinem Bash-Skript unterstützen (zum Beispiel
find ... | tar ...
).Die einzige Kombination, die die oben genannten Anforderungen erfüllt, ist:
quelle
Dies wird in Python 3-Unterprozessbeispielen unter "Warten auf asynchrones Beenden des Befehls" behandelt:
Der Prozess wird gestartet, sobald der Vorgang
await asyncio.create_subprocess_exec(...)
abgeschlossen ist. Wenn es zum Zeitpunktawait proc.communicate()
Ihres Anrufs noch nicht fertig ist , wartet es dort, um Ihnen Ihren Ausgabestatus mitzuteilen. Wenn es fertig ist,proc.communicate()
wird sofort zurückkehren.Das Wesentliche hier ist ähnlich wie bei Terrels Antwort aber ich denke, die Antwort von Terrels scheint die Dinge .
Siehe
asyncio.create_subprocess_exec
für weitere Informationen.quelle