In welchen Fällen wird SIGHUP beim Abmelden nicht an einen Job gesendet?

10

Ich habe eine Antwort von einem Benutzer gelesen, der behauptet, dass sie ausgeführt wird

foo 2>&1 >& output.log &

würde dazu führen foo, dass die Ausführung auch dann fortgesetzt wird, wenn sie sich abmelden. Laut diesem Benutzer funktionierte dies sogar über SSH-Verbindungen.

Ich habe das nicht wirklich geglaubt, da ich den Eindruck hatte, dass im Falle einer Trennung von SSH oder der Beendigung des TTY die Shell und damit ihre Prozesse ein SIGHUP erhalten würden, wodurch sie beendet würden. Dies unter meiner Annahme, war der einzige Grund für die Verwendung nohupin solchen Fällen oder tmux, screenet al.

Ich habe dann in glibcs ​​Handbuch geschaut :

Dieses Signal wird auch verwendet, um die Beendigung des Steuerungsprozesses auf einem Terminal an Jobs zu melden, die dieser Sitzung zugeordnet sind. Diese Beendigung trennt effektiv alle Prozesse in der Sitzung vom steuernden Terminal.

Dies scheint meine Gedanken zu bestätigen. Aber wenn man weiter schaut, heißt es :

Wenn der Prozess ein Sitzungsleiter ist, der über ein steuerndes Terminal verfügt, wird ein SIGHUP-Signal an jeden Prozess im Vordergrundjob gesendet, und das steuernde Terminal wird von dieser Sitzung getrennt.

Bedeutet dies also, dass Jobs im Hintergrund kein SIGHUP erhalten?

Zu meiner weiteren Verwirrung führte ich eine interaktive Zsh-Sitzung durch, lief yes >& /dev/null &und tippte exit, als Zsh mich warnte, dass ich laufende Jobs hatte, und exitsagte mir nach einem zweiten Tippen , dass es einen Job SIGHUPIERT hatte. Wenn Sie in Bash genau dasselbe tun, läuft der Job…

slhck
quelle
Ich hatte in der Vergangenheit Probleme mit einem Server, der plötzlich über ssh getrennt wurde, und mein Prozess lief einfach weiter, aber ohne dass etwas damit verbunden war. Deshalb musste ich mich erneut anmelden und SIGHUP / TERM / KILL senden, um sie zu beenden. Nach der gleichen Logik habe ich gerade getestet, getippt logoutund yesläuft noch.
Braiam
Zusätzlich dazu, ob SIGHUP gesendet wird oder nicht, sind weitere Faktoren, ob ein Prozess einen Signalhandler definiert hat (und SIGHUP abfängt) oder eine Signalmaske, ob er beim Senden dieses Signals beendet wird. Nur weil es nach dem Abmelden weiterhin ausgeführt wird, heißt das nicht, dass dieses Signal nicht gesendet wurde
Tim B,
Beziehen Sie sich auf diese Frage: serverfault.com/questions/115999/… ? Die Antwort scheint dort zu finden - es ist RedHat, das standardmäßig nicht shopt einstellt. Es ist RedHats besondere Konfigurations-Eigenart.
Boris Burkov
@ Bob Nein, ich habe dieses noch nie gesehen, aber es ist eine gute Ressource. Vielen Dank!
Slhck
Ich bin froh, dass es geholfen hat. Eigentlich bezieht sich Raphael auch auf dieses Thema.
Boris Burkov

Antworten:

17

Bash scheint das SIGHUPnur zu senden, wenn es selbst ein empfangen hat SIGHUP, was beispielsweise auftritt, wenn ein virtuelles Terminal geschlossen wird oder wenn die SSH-Verbindung unterbrochen wird. Aus der Dokumentation :

Die Shell wird standardmäßig nach Erhalt eines SIGHUP beendet. Vor dem Beenden sendet eine interaktive Shell das SIGHUP erneut an alle laufenden oder gestoppten Jobs. Gestoppte Jobs werden SIGCONT gesendet, um sicherzustellen, dass sie das SIGHUP erhalten. Um zu verhindern, dass die Shell das SIGHUP-Signal an einen bestimmten Job sendet, sollte es mit dem eingebauten Disown (siehe Job Control Builtins) aus der Jobtabelle entfernt oder markiert werden, um SIGHUP nicht mit disown -h zu empfangen.

Wenn Sie also + eingeben exitoder drücken , bleibt der gesamte Hintergrundprozess erhalten, da dies kein Auflegesignal an den Bash sendet.CtrlD

Sie können Bash zwingen, Sie vor der Tatsache zu warnen, dass noch Hintergrundprozesse mit ausgeführt werden

shopt -s checkjobs

Es besteht die Möglichkeit, den SIGHUPOn-Exit zu senden, wenn Sie sich in einer interaktiven Shell befinden ( siehe hier ). Aber es funktioniert nicht auf meinem Computer mit Bash 4.2.25. Vielleicht funktioniert es für Sie

shopt -s huponexit
Raphael Ahrens
quelle
Wenn also eine SSH-Verbindung unterbrochen SIGHUPwird, andernfalls mit einem sauberen Exit weiterhin Jobs ausgeführt werden? Das erklärt, was ich gesehen habe.
Slhck
Ja. Das Auflegesignal ist nur für den Sonderfall da, wenn die Verbindung zum Benutzer unterbrochen ist.
Raphael Ahrens
Lassen Sie uns diese Diskussion im Chat fortsetzen .
Martin Kunev
@npostavs danke für die Informationen, die ich der Antwort hinzugefügt habe.
Raphael Ahrens