Ich weiß, dass ich &
einen Befehl anhängen kann , um den Prozess im Hintergrund auszuführen.
Ich stelle eine SSH-Verbindung zu einer Ubuntu 12.04-Box her und starte ein Python-Programm mit $python program.py &
- aber wenn ich das Terminalfenster schließe, erhalte ich die Meldung, dass das Schließen des Terminals den laufenden Prozess abbricht .
Warum ist das? Ich verwende das kaufmännische Und, um den Prozess im Hintergrund auszuführen. Wie kann ich es zum Laufen bringen, unabhängig davon, ob ich in SSH angemeldet bin?
Antworten:
Wenn Sie ein Terminalfenster schließen, sendet der Terminalemulator ein SIGHUP an den Prozess, den er ausführt, Ihre Shell. Ihre Shell leitet das SIGHUP dann an alles weiter, was ausgeführt wird. Auf Ihrem lokalen System ist dies das ssh. Das SSH leitet das SIGHUP dann an das weiter, was gerade ausgeführt wird, die Remote-Shell. Ihre Remote-Shell sendet dann ein SIGHUP an alle Prozesse, Ihr Hintergrundprogramm.
Es gibt zwei Möglichkeiten, dies zu umgehen.
disown
Befehl nach dem Hintergrund Ihres Prozesses. Dadurch wird die Shell darüber vergessen.nohup
(nohup $python program.py &
) voran . Dies bewirkt dasselbe, jedoch unter Verwendung eines Zwischenprozesses. Grundsätzlich ignoriert es das SIGHUP-Signal und führt dann das Programm aus, das die Einstellung übernimmt, und beendet es dann. Das gestartete Programm ist kein Kind der Shell, und die Shell weiß nichts darüber. Und wenn kein Signalhandler für SIGHUP installiert wird, wird die Ignorieraktion trotzdem beibehalten.logout
anstatt das Terminalfenster zu schließen. Wenn Sie verwendenlogout
, ist dies keine SIGHUP, und die Shell sendet keine SIGHUP an ihre untergeordneten Elemente.Darüber hinaus müssen Sie sicherstellen, dass Ihr Programm nicht über STDOUT oder STDERR auf das Terminal schreibt, da beide nach dem Beenden des Terminals nicht mehr vorhanden sind. Wenn Sie sie nicht auf etwas umleiten
/dev/null
, wird das Programm weiterhin ausgeführt, aber wenn es versucht, auf sie zu schreiben, wird ein SIGPIPE ausgegeben, und die Standardaktion von SIGPIPE besteht darin, den Prozess abzubrechen.quelle
ssh
Sterben dazu , dass die Verbindung unterbrochen wird und die Verbindungsshd
am anderen Ende unterbrochen wird. Das SSHD, das die Masterseite des Pseudoterminals steuert, auf dem die Remote-Shell ausgeführt wird, ist ein Auflegen (es ist wie das Ziehen des Steckers an einem realen Terminal), sodass das System ein SIGHUP an die Remote-Shell sendet.nohup
einenohup.out
Datei mit der Ausgabe des Programms erstellt wird, mit dem Sie beginnen. Es kann ärgerlich sein, diese Datei jedes Mal zu löschen, wenn Sie nohup zum Starten einer App auf diese Weise verwendet haben (oder wenn Sie die Ausgabe an umleiten müssen/dev/null
).nohup python program.py &
würde ichsetsid python program.py
stattdessen empfehlen , was das Programm sofort verleugnet.Der Prozess läuft im Hintergrund im Terminal, aber die Ausgabe von
stdout
(undstderr
) wird weiterhin zum Terminal gesendet. Um dies zu beenden, fügen Sie> /dev/null 2>&1
vor dem hinzu&
, um beide Ausgänge umzuleiten,/dev/null
und stellen Siedisown
sicher, dass der Prozess nach dem Schließen des Terminals nicht abgebrochen wird:In Ihrem Fall wäre dies:
quelle
Der
&
Bediener trennt Befehle, die parallel ausgeführt werden sollen, genauso wie;
Befehle, die in Reihe ausgeführt werden sollen. Beide Arten von Befehlen werden weiterhin als untergeordnetes Element des Shell-Prozesses ausgeführt .Wenn Sie also die Shell schließen, die diese Kinder gestartet hat, werden auch die Kinder geschlossen.
Was Sie anscheinend wollen, ist ein Daemon-Prozess , der wesentlich kniffliger ist, da er sich vollständig vom übergeordneten Prozess trennen muss. Die Shell hat normalerweise keine einfache Möglichkeit, dies zu tun.
quelle
Wenn Sie sich abmelden, werden normalerweise auch die mit der Anmeldesitzung verbundenen Hintergrundprozesse abgebrochen. Wenn Sie möchten, dass sie von der Sitzung getrennt werden, führen Sie sie mit aus
nohup
.quelle
&
Führen Sie nach dem mit kaufmännischem Und ( ) endenden Befehl an der Eingabeaufforderung den folgenden Befehl ausbg
:Dadurch wird der Befehl "&" in den Hintergrund gestellt
Dadurch werden die Jobs aufgelistet, die im Hintergrund ausgeführt werden
Dadurch wird Job 1 in den Vordergrund gerückt
Ein anderer Weg (um sich abmelden zu können)
Es können mehrere Zeilen an den
at
Befehl übergeben werden, bevor das ^ d (Strg-D)angezeigt wird
man at
.quelle