Warum leben Hintergrundjobs, die von meiner Shell gestartet werden, länger als die übergeordnete Shell und steuern Terminals?

6

Es wird allgemein gesagt, dass "&" den Prozess in die Hintergrundausführung versetzt, dieser Prozess jedoch beendet wird, wenn das Terminal geschlossen wird. Aber nach allem, was ich sehe, war alles, was ich in den Hintergrund geschickt habe, noch lange nach dem Schließen des Terminals aktiv. Zum Beispiel:

$ tail -f /var/log/messages/ &

Dieser Prozess würde weiterhin ausgeführt, selbst wenn sich unter dem Benutzer, der ihn gestartet hat, kein anderer Prozess befindet und alle Terminals längst nicht mehr vorhanden sind. Warum ist das so?

Rogach
quelle
Mögliches Duplikat des Unterschieds zwischen Nohup, Disown und &
Gilles 'SO - hör auf böse zu sein'
1
Die Frage wäre weniger ein Duplikat, wenn der Titel so geändert würde, dass er seinem Inhalt entspricht. Dies entspricht eher der Frage: "Warum leben Hintergrundjobs, die von meiner Shell gestartet wurden, länger als die übergeordnete Shell und steuern Terminals?"
jw013

Antworten:

7

Nur eine Vermutung (dies ist bashspezifisch): In der Dokumentation zur huponexitShell-Option heißt es

Wenn festgelegt, sendet Bash SIGHUP an alle Jobs, wenn eine interaktive Anmeldeshell beendet wird

Auf meinem System scheint es nicht standardmäßig eingestellt zu sein. Sie können mit überprüfen

shopt -p huponexit

Wenn die Ausgabe enthält -u, ist sie nicht gesetzt.

jw013
quelle
In der Tat enthält es -u.
Rogach
5

Ein Prozess, der mit '&' anstelle von nohup in den Hintergrund gestellt wird, stirbt ab, wenn das Terminal für die Eingabe oder Ausgabe benötigt wird und feststellt, dass es nicht vorhanden ist. In diesem Fall tailwird wahrscheinlich beendet, wenn etwas in / var / log / messages schreibt, obwohl möglicherweise ein Pufferproblem vorliegt, das es verzögert, bis mehr als eine Nachricht geschrieben wird.

Das Starten eines Prozesses mit ./foo > /dev/null 2&1 < /dev/nullentspricht in etwa dem Starten mit nohup. Grundsätzlich kümmert sich nohup nur darum, alle Ein- und Ausgänge umzuleiten, die noch nicht vom Terminal weggeleitet wurden.

Paul Tomblin
quelle
3

Das kaufmännische Und &stellt den Prozess in den Hintergrund. Dateideskriptoren (stdout, stderr, stdin) sind nicht betroffen. Beim Beenden der Shell sendet die Shell SIGHUPan alles, was sie erzeugt hat. Wenn diese Shell geschlossen wird, wird der Hintergrundprozess empfangen SIGHUPund wahrscheinlich beendet. In einigen Shells (bash, zsh) können Sie dies verhindern, indem Sie den Befehl verwenden, disownder die Shell anweist, sie SIGHUPbeim Schließen der Shell nicht zu senden , und der Prozess wird weiterhin ausgeführt.

Sie können auch das Äquivalent von "Hintergrund mit einem kaufmännischen Und" ausführen, indem Sie senden SIGSTOP(normalerweise Strg-Z in Ihrem Terminal) und dann den Prozess hinterlegen ( bg).

nohup ignoriert SIGHUP. Diese Signaldisposition wird dann an den von Ihnen ausgeführten untergeordneten Prozess übergeben. nohup prüft auch, wohin stdout geht, und wenn es zum Terminal geht, leitet es stdout und stderr in eine Datei um. Nach der Änderung der Signaldisposition und der möglichen Umleitung wird Ihr Prozess im Hintergrund ausgeführt.

Also, was ist der Unterschied?

Ein Hintergrundprozess wird nicht ignoriert SIGHUP, obwohl Sie Ihrer Shell mitteilen können, dass sie ihn nicht mit Verleugnung senden soll. Wenn nicht verhindert, nohupleitet stdout zu nohup.out-Dateien um, die ich eher hasse, wenn ich nur nohup.out-Dateien löschen muss, die zufällig auf meiner Festplatte verstreut sind.

Es gibt auch setsid, was Ihren Prozess zu einem Prozessgruppenleiter macht. Ein Prozessgruppenleiter wird SIGHUPvon keiner Shell an ihn gesendet. setsidmacht nicht viel mit stdout / stderr, und ich neige dazu, setsidstattdessen zu verwenden nohup.

Reiche Homolka
quelle