Ich versuche zu verstehen, warum nohup
Hintergrundbefehle in SSH verwendet werden müssen. Meine Shell ist CSH unter CentOS.
Der folgende Hintergrundbefehl wird auch nach dem Beenden von SSH weiter ausgeführt. Ich hatte erwartet, dass dies nur passiert, wenn
nohup
dem Befehl ein Präfix vorangestellt wird.Welches Szenario
nohup
wäre erforderlich?ssh host 'sleep 80 >& /dev/null &'
Ich habe auch eine interaktive Shell ausprobiert und die PID des Hintergrundjobs existiert nach dem Beenden von SSH immer noch auf dem Host.
ssh host sleep 80 >& /dev/null & exit
Ich habe auch versucht, die interaktive Sitzung mit
kill -HUP PID
statt zu beendenexit
, und die PID des Hintergrundjobs ist nach dem Beenden von SSH weiterhin auf dem Host vorhanden.
Mache ich etwas falsch?
Antwort1
Nein, einHintergrundDie Prozessgruppe (der Job) wird standardmäßig NICHT beendet, wenn der Sitzungsleiter (die Shell) beendet wird oder wenn das steuernde Terminal heruntergefahren wird.
Dies geschieht nur in einigen Sonderfällen:
(1)Der Hintergrundjob istgestoppt, in diesem Fall wird ihm ein SIGHUP
/ SIGCONT
Signalpaar vomKernelWenn das SIGHUP
Signal von einem Prozess nicht abgefangen oder ignoriert wird, wird der Prozess beendet.
Die Definition eines gestoppten Jobs lautet: Jeder Job, der einen gestoppten Prozess enthält. Ein ProzessSchlafenbei einem blockierenden Systemaufruf wie nanosleep(2)
oder read(2)
gilt NICHT als gestoppt.
(2)Ein Prozess versucht, Daten aus dem nicht mehr vorhandenen Terminal zu lesen oder darauf zu schreiben und wird (von selbst) beendet, weil dabei Fehler auftreten.
(3)Der Job ist eigentlich einVordergrundArbeit. DieKernelsendet ein SIGHUP
Signal an die Vordergrundprozessgruppe, wenn der Sitzungsleiter/Steuerprozess (also die Shell) beendet wird. Dem Steuerprozess selbst wird signalisiert, SIGHUP
wenn sein Steuerterminal abgebaut wird, was normalerweise zu seiner Beendigung führt.
Auch Befehle, die mit beginnen, &
sind eigentlich Teil desVordergrundProzessgruppe, wenn sie von einer Shell ohne Job-Kontrolle gestartet werden (was in den meisten Shells --aber nicht in csh-- die Standardeinstellung ist, wennSkripteUndUnterschalen).
(4)Sie verwenden eine Shell wie bash
oder zsh
, die sich besondere Mühe gibt, ein SIGHUP
Signal an alle ihre Jobs zu senden, wenn sie selbst mit signalisiert wird SIGHUP
(gemäß Punkt 3. oben, wobei die Shell der steuernde Prozess ist) oder einfach, wenn sie beendet wird (letzteres ist nur die Standardeinstellung in zsh
, aber nicht die Standardeinstellung und unterliegt der shopt huponexit
Option in Bash).
DerCSH-Shell(entweder das echte csh
oder tcsh
)hat dieses Verhalten nichtvon bash
oder zsh
. In tcsh
(aber NICHT im echten csh
) können Sie einen Befehl mit dem integrierten Befehl starten hup
, um ihn beim Beenden der Shell ausführen zu lassen:
tcsh% hup sleep 3600 &
tcsh% exit
$ pgrep sleep
[nothing]
(5)Ihr Init-System unternimmt alle Anstrengungen, um beendete Benutzersitzungen zu bereinigen. In der Standardkonfigurationsystemdsignalisiert alle Prozesse von einemUmfangmit einem SIGTERM
gefolgt von einem SIGKILL
nach einer Verzögerung, nohup
wird Ihnen also NICHT dabei helfen. Außerdem ist systemds Idee einesUmfangstimmt nicht mit einer Unix-Prozess-Sitzung überein, daher setsid(1)
kann diese auch nicht durch Ausführen eines Befehls mit verlassen werden.
KillUserProcesses=yes
Sie können das Verhalten von systemd wahrscheinlich ändern, indem Sie die Optionen , KillMode=control-group
, KillSignal=SIGTERM
und von den Standardeinstellungen abweichen SendSIGKILL=yes
.