Ich versuche, ein Shell-Skript auf die viel besser lesbare Python-Version zu portieren. Das ursprüngliche Shell-Skript startet mehrere Prozesse (Dienstprogramme, Monitore usw.) im Hintergrund mit "&". Wie kann ich den gleichen Effekt in Python erzielen? Ich möchte, dass diese Prozesse nicht absterben, wenn die Python-Skripte abgeschlossen sind. Ich bin mir sicher, dass es irgendwie mit dem Konzept eines Daemons zusammenhängt, aber ich konnte nicht einfach herausfinden, wie das geht.
295
subprocess.Popen()
der neue empfohlene Weg seit 2010 ist (wir sind jetzt im Jahr 2015) und (3) die doppelte Frage, die hier umgeleitet wird, auch eine akzeptierte Antwort über hatsubprocess.Popen()
. Prost :-)subprocess.Popen("<command>")
mit einer <Befehl> -Datei erfolgen, die von einem geeigneten Shebang geführt wird. Funktioniert perfekt für mich (Debian) mit Bash- und Python-Skripten, impliziert implizitshell
s und überlebt den übergeordneten Prozess.stdout
geht zum selben Terminal wie das der Eltern. Das funktioniert also ähnlich wie&
in einer Shell, die von OPs angefordert wurde. Aber zum Teufel, alle FragenAntworten:
Hinweis : Diese Antwort ist weniger aktuell als 2009. Die Verwendung des
subprocess
in anderen Antworten gezeigten Moduls wird jetzt in den Dokumenten empfohlenWenn Sie möchten, dass Ihr Prozess im Hintergrund startet, können Sie ihn entweder
system()
wie Ihr Shell-Skript verwenden und aufrufen oder wie folgtspawn
:(oder alternativ können Sie die weniger tragbare
os.P_NOWAIT
Flagge ausprobieren ).Siehe die Dokumentation hier .
quelle
subprocess
uns die Leute, die die Verwendung vorschlagen , einen Hinweis geben, wie man einen Prozess löstsubprocess
?Während die Lösung von jkp funktioniert, besteht die neuere Vorgehensweise (und die in der Dokumentation empfohlene Vorgehensweise) darin, das
subprocess
Modul zu verwenden. Für einfache Befehle ist es gleichbedeutend, aber es bietet mehr Optionen, wenn Sie etwas Kompliziertes tun möchten.Beispiel für Ihren Fall:
Dies wird ausgeführt
rm -r some.file
im Hintergrund ausgeführt. Beachten Sie, dass der Aufruf.communicate()
des von zurückgegebenen ObjektsPopen
blockiert wird, bis es abgeschlossen ist. Tun Sie dies also nicht, wenn Sie möchten, dass es im Hintergrund ausgeführt wird:Siehe die Dokumentation hier .
Zur Verdeutlichung auch: "Hintergrund", wie Sie ihn hier verwenden, ist ein reines Shell-Konzept; Technisch gesehen meinen Sie damit, dass Sie einen Prozess erzeugen möchten, ohne ihn zu blockieren, während Sie darauf warten, dass er abgeschlossen ist. Ich habe hier jedoch "Hintergrund" verwendet, um auf Shell-Hintergrund-ähnliches Verhalten zu verweisen.
quelle
Popen()
, um das Blockieren des Hauptthreads zu vermeiden. Wenn Sie einen Daemon benötigen, schauen Sie sich daspython-daemon
Paket an, um zu verstehen, wie sich ein genau definierter Daemon verhalten soll. Ihre Antwort ist in Ordnung, wenn Sie alles entfernen, was mit "Aber seien Sie vorsichtig" beginnen, mit Ausnahme des Links zu den Dokumenten des Unterprozesses.Sie möchten wahrscheinlich die Antwort auf "So rufen Sie einen externen Befehl in Python auf" .
Der einfachste Ansatz ist die Verwendung der
os.system
Funktion, z.Grundsätzlich wird alles, was Sie an die
system
Funktion übergeben, so ausgeführt, als hätten Sie es in einem Skript an die Shell übergeben.quelle
Ich habe das hier gefunden :
Unter Windows (Win XP) wird der übergeordnete Prozess erst beendet, wenn der
longtask.py
seine Arbeit beendet hat. Es ist nicht das, was Sie in CGI-Skript wollen. Das Problem ist nicht spezifisch für Python. In der PHP-Community sind die Probleme dieselben.Die Lösung besteht darin, das
DETACHED_PROCESS
Prozesserstellungsflag an die zugrunde liegendeCreateProcess
Funktion in der Win-API zu übergeben. Wenn Sie pywin32 installiert haben, können Sie das Flag aus dem win32process-Modul importieren. Andernfalls sollten Sie es selbst definieren:quelle
Verwenden Sie
subprocess.Popen()
mit demclose_fds=True
Parameter, der den erzeugte Unterprozess ermöglicht es von dem Python abgenommen wird Prozess selbst und auch nach Python - Exits ausgeführt wird .https://gist.github.com/yinjimmy/d6ad0742d03d54518e9f
quelle
Sie möchten wahrscheinlich das OS-Modul untersuchen, um verschiedene Threads zu forken (indem Sie eine interaktive Sitzung öffnen und Hilfe (OS) ausgeben). Die relevanten Funktionen sind Fork und alle Exec-Funktionen. Um Ihnen eine Vorstellung davon zu geben, wie Sie beginnen sollen, fügen Sie so etwas in eine Funktion ein, die die Verzweigung ausführt (die Funktion muss eine Liste oder ein Tupel 'args' als Argument verwenden, das den Namen des Programms und seine Parameter enthält. Möglicherweise möchten Sie dies auch stdin, out und err für den neuen Thread definieren):
quelle
os.fork()
ist wirklich nützlich, hat aber den bemerkenswerten Nachteil, dass es nur auf * nix verfügbar ist.threading
: stackoverflow.com/a/53751896/895245 Ich denke, das könnte unter Windows funktionieren.Beide erfassen die Ausgabe und laufen im Hintergrund mit
threading
Wie in dieser Antwort erwähnt , blockiert der Prozess , wenn Sie die Ausgabe mit erfassen
stdout=
und dann versuchenread()
, dies zu tun.Es gibt jedoch Fälle, in denen Sie dies benötigen. Zum Beispiel wollte ich zwei Prozesse starten , die über einen Port zwischen ihnen kommunizieren, und ihre Standardausgabe in einer Protokolldatei und Standardausgabe speichern.
Das
threading
Modul ermöglicht es uns, dies zu tun.Schauen Sie sich zunächst in dieser Frage an, wie der Ausgabeumleitungsteil alleine ausgeführt wird: ausführen: Python Popen: Schreiben Sie gleichzeitig in die Standard- UND Protokolldatei
Dann:
main.py.
sleep.py
Nach dem Rennen:
stdout wird alle 0,5 Sekunden aktualisiert, damit alle zwei Zeilen Folgendes enthalten:
und jede Protokolldatei enthält das entsprechende Protokoll für einen bestimmten Prozess.
Inspiriert von: https://eli.thegreenplace.net/2017/interacting-with-a-long-running-child-process-in-python/
Getestet unter Ubuntu 18.04, Python 3.6.7.
quelle