Nachdem ssh
ich mich angemeldet habe , gebe ich diesen Befehl ein bash
:
sleep 50000000000000 &
Dann habe ich kill -9
den sleep
übergeordneten Prozess des Prozesses (dh bash
). Dann wird das Terminalfenster gleichzeitig getrennt.
Wenn ich mich erneut anmelde, stelle ich fest, dass der sleep
Prozess noch läuft.
Frage : Warum kann der sleep
Prozess überleben, wenn ich mich abmelde und das Terminal geschlossen ist? In meinen Augen wird alles außer Dämonen und nohup
Programmen beim Abmelden getötet. Wenn sleep
ich auf diese Weise überleben kann, bedeutet das, dass ich diese Methode anstelle des nohup
Befehls verwenden kann?
&
Der Prozess wird in den Hintergrund verschoben (wie bei einem Daemon) und läuft weiter, obwohl Sie abgemeldet sind.Antworten:
Tl; dr:
Sofern für die von
bash
erzeugte Instanzssh
diehuponexit
Option festgelegt ist, wird kein Prozess beim Beenden / Abmelden auf irgendeine Weise beendet. Wenn diehuponexit
Option festgelegt ist, ist die Verwendungkill -9
in der Shell keine gute Alternative zur Verwendungnohup
in den untergeordneten Prozessen der Shell.nohup
Auf den untergeordneten Prozessen der Shell werden sie weiterhin vor SIGHUPs geschützt, die nicht von der Shell stammen, und selbst wenn dies nicht wichtignohup
ist , ist dies immer noch zu bevorzugen, da die Shell ordnungsgemäß beendet werden kann.In
bash
gibt es eine Option namenshuponexit
, die, wenn gesetzt,bash
SIGHUP seine Kinder beim Beenden / Abmelden macht;In interaktiven Instanzen ohne Anmeldung
bash
, z. B. in einer vonbash
erzeugten Instanzgnome-terminal
, wird diese Option ignoriert. obhuponexit
gesetzt oder nicht gesetzt, werdenbash
die Kinderbash
beim Verlassen niemals von SIGHUPped ;In interaktiven Anmeldeinstanzen
bash
, z. B. in einer vonbash
erzeugten Instanzssh
, wird diese Option nicht ignoriert (sie ist jedoch standardmäßig deaktiviert). Wennhuponexit
festgelegt,bash
werden die untergeordneten Elementebash
beim Beenden / Abmelden von SIGHUPped . Wenn dies nicht festgelegthuponexit
ist, werdenbash
die Kinderbash
beim Beenden / Abmelden nicht von SIGHUPped .Im Allgemeinen wird das Beenden / Abmelden von einer interaktiven Anmeldeinstanz
bash
, sofern diehuponexit
Option nicht aktiviert ist, die Shell nicht zu ihren untergeordneten SIGHUP machen, und das Beenden / Abmelden von einer interaktivenbash
Instanz ohne Anmeldung macht die Shell nicht zu ihren untergeordneten SIGHUP ungeachtet;Dies ist jedoch irrelevant in diesem Fall: mit
kill -9
sleep
unabhängig überleben, weil seinen Eltern - Prozess zu töten (bash
) keine Chance läßt letztere tun alles , um die alten (also beispielsweise , wenn die aktuellebash
Instanz ist eine Login -bash
Instanz und diehuponexit
Option wurde gesetzt, um es zu registrieren).Im Gegensatz zu anderen Signalen (wie einem SIGHUP-Signal, an das gesendet wird
bash
) wird ein SIGKILL-Signal niemals an die untergeordneten Prozesse eines Prozesses weitergegeben und dahersleep
nicht einmal getötet.nohup
startet einen Prozess, der gegen SIGHUP-Signale immun ist, was etwas anderes ist; Dadurch wird verhindert, dass der Prozess beim Empfang eines SIGHUP-Signals hängen bleibt, das in diesem Fall von der interaktiven Anmeldeinstanz empfangen werden kann,bash
falls diehuponexit
Option festgelegt und die Shell beendet wurde. Wenn Sie also technisch gesehennohup
einen Prozess in einer interaktiven Anmeldeinstanzbash
mit derhuponexit
Option "Nicht gesetzt" starten, wird verhindert, dass der Prozess beim Empfang eines SIGHUP-Signals hängen bleibt. Wenn Sie die Shell jedoch verlassen / abmelden, wird sie unabhängig davon nicht SIGHUP.Im Allgemeinen gibt es jedoch
nohup
keinen Grund, diekill -9
On-Parent-Methode dernohup
On-Child-Methode vorzuziehen , wenn dies erforderlich ist, um zu verhindern, dass SIGHUP-Signale von der übergeordneten Shell kommen . stattdessen sollte es das Gegenteil sein.Das Töten des Elternteils mit der
kill -9
Methode lässt dem Elternteil keine Möglichkeitnohup
, ordnungsgemäß zu beenden , während das Starten des Kindes mit der Methode es dem Elternteil ermöglicht, durch andere Signale wie SIGHUP beendet zu werden (um ein Beispiel zu erstellen, das im Kontext sinnvoll ist eines Kindes begann zu verwendennohup
), die es ermöglichen, anmutig zu beenden.quelle
ps -e | grep process
sollten Sie die Prozesse zusammen mit der PIDpgrep -x process
auflisten (oder besser, wenn Sie sicher sind, dass Sie diesem einzelnen Prozess und nicht den nicht zugewiesenen Dingen entsprechen). Das Problem ist, dass, wenn Sie einen Prozess beenden,kill -9
dessen Kinder im Besitz von sindupstart
, daher ihre ursprüngliche PPID verloren geht und ihre PPID sich in die PID des Emporkömmlings ändert, wodurch sie nicht wiederzuerkennen sind (AFAIK), aber für ihren Namen oder ihre PIDnohup
kann nicht verhindert werden, dass ein Prozess beim Empfang eines SIGHUP-Signals vom übergeordneten Prozess auflegt ? Ich versuche, einen Prozess im Hintergrund (in einem PuTTY SSH-Shell-Terminal) von auszuführennohup <command> <arg> &
. Wenn ich mich durch Klicken auf dieX
Schaltfläche PuTTY abmelde, wird der Hintergrundprozess sofort beendet. Wenn ich mich durch Eingabeexit
des PuTTY SSH-Shell-Terminals abmelde, wird der Prozess im Hintergrund fortgesetzt.bash
Standardmäßig wird das HUP-Signal beim Beenden nicht an untergeordnete Prozesse gesendet . Genauer gesagt (danke @kos), es funktioniert nie für Nicht-Login-Shells .Sie können bash so konfigurieren, dass es für Login-Shells ausgeführt wird, wenn Sie die Option festlegen
huponexit
. Führen Sie in einem Terminal Folgendes aus:(dies startet eine neue "Login" Shell)
Überprüfen Sie nun den
sleep
Vorgang:... läuft nicht: Es hat das HUP-Signal empfangen und wie angefordert beendet.
quelle
sleep 1000 & ; exit
dassleep
überlebe? Beachten Sie, dass wenn ichkill -HUP
densleep
Prozess, wird es beendet . Und selbst wennhuponexit
gesetzt,sleep
überlebt der. Verwirrt ... (Ich werde versuchen, die Antwort besser zu verstehen und zu ändern, sonst werde ich sie löschen).kill -9
ist wirklich nicht der Weg, den man gehen sollte. Es ist, als würde man mit einer Waffe auf den Fernseher schießen, um ihn auszuschalten. Neben der komödiantischen Komponente gibt es keinen Vorteil. Prozesse können nicht abfangen oder ignorierenSIGKILL
. Wenn Sie dem Prozess keine Chance geben, seine Arbeit zu beenden und zu bereinigen, bleiben möglicherweise beschädigte Dateien (oder ein anderer Status) in der Nähe und können nicht erneut gestartet werden.kill -9
ist die letzte Hoffnung, wenn nichts anderes funktioniert.Was passiert in Ihrem Fall:
Der übergeordnete Prozess von
sleep
ist die aktuell ausgeführtebash
Shell. Wenn Siekill -9
diesen Bash ausführen, hat der Bash-Prozess nicht die Möglichkeit, einenSIGHUP
an einen seiner untergeordneten Prozesse zu senden , daSIGKILL
(der von gesendet wirdkill -9
) vom Prozess nicht erfasst werden kann. Der Schlafprozess läuft weiter. Schlaf wurde jetzt ein verwaister Prozess .Der Init (PID 1) -Prozess führt einen Mechanismus aus, der als Reparenting bezeichnet wird. Das bedeutet, dass der Init-Prozess jetzt das übergeordnete Element dieses verwaisten Prozesses wird. init ist eine Ausnahme. Prozesse können untergeordnet werden, da Prozesse erfasst werden, die ihren ursprünglichen übergeordneten Prozess verloren haben. Übrigens: Ein Daemon (wie
sshd
) macht das, wenn er "in den Hintergrund geht".Wenn dies nicht passieren würde, würde der verwaiste Prozess später (wenn er abgeschlossen ist) zu einem Zombie-Prozess. Dies ist, was passiert, wenn
waitpid()
es nicht aufgerufen wird (eine Verantwortung des übergeordneten Prozesses, die nicht erfüllt werden kann, wenn dieser Prozess beendet wurde). init ruftwaitpid()
in einem bestimmten Intervall auf, um Zombiekinder zu vermeiden.quelle
TERM
oderHUP
huponext
. Und TERM wird warten, bis der Schlaf beendet ist. Im Falle des Schlafbefehls der OP wären es Tausende von Jahren =)Das
&
startet den Prozess im Hintergrund. Wenn Sie eingebenps -ef
, sehen Sie, dass die übergeordnete Prozess-ID (PPID) Ihres Schlafes Ihre Bash ist. Dann abmelden und erneut anmelden. Der Prozess läuft nach dem Abmelden weiter. Nachdem Sie sich zum zweiten Mal angemeldet haben,ps -ef
werden Sie erneut ausgeführt. Sie werden sehen, dass jetzt das übergeordnete Element Ihres Schlafprozesses mit der ID "1" verarbeitet wird. Das ist init, das übergeordnete Element aller Prozesse.quelle
Wenn Sie verwenden,
&
wird das Programm als Hintergrund ausgeführt. Um das Programm im Hintergrund zu sehen, verwenden Sie denbg
Befehl, und um es wieder als Vordergrund auszuführen, führen Sie es ausfg
.Ja, es gibt viele Möglichkeiten, das Programm am Laufen zu halten, selbst wenn das Hauptterminal beendet ist.
quelle
huponexit
nur bei Login-Shells funktioniert, z. B. bei einer Shell, die überssh
(und nicht beispielsweise bei einer Shell, die übergnome-terminal
) erhalten wurde