Nachdem ich mich über angemeldet habe ssh
, gebe ich diesen Befehl ein bash
:
sleep 50000000000000 &
Dann schalte ich kill -9
den sleep
übergeordneten Prozess des Prozesses (also bash
) ein. Dann wird gleichzeitig die Verbindung zum Terminalfenster getrennt.
Wenn ich mich erneut anmelde, stelle ich fest, dass der sleep
Vorgang noch aktiv ist.
Frage: Warum kann der sleep
Prozess überleben, wenn ich mich abmelde und das Terminal geschlossen wird? Meiner Meinung nach nohup
wird beim Abmelden alles außer Daemons und Programmen beendet. Wenn sleep
er auf diese Weise überleben kann, bedeutet das, dass ich diese Methode anstelle des nohup
Befehls verwenden kann?
Antwort1
Kurz gesagt:
Warum kann der
sleep
Prozess überleben, wenn ich mich abmelde und das Terminal geschlossen wird? Meiner Meinung nachnohup
wird beim Abmelden alles außer Daemons und Programmen beendet. Wennsleep
er auf diese Weise überleben kann, bedeutet das, dass ich diese Methode anstelle desnohup
Befehls verwenden kann?
Sofern die bash
von erzeugte Instanz nicht ssh
über die huponexit
festgelegte Option verfügt, wird kein Prozess beim Beenden/Abmelden auf irgendeine Weise beendet. Wenn die huponexit
Option festgelegt ist, kill -9
ist die Verwendung auf der Shell keine gute Alternative zur Verwendung nohup
auf den untergeordneten Prozessen der Shell. Die Verwendung nohup
auf den untergeordneten Prozessen der Shell schützt diese weiterhin vor SIGHUPs, die nicht von der Shell kommen, und ist selbst dann vorzuziehen, wenn dies nicht wichtig ist, nohup
da die Shell dadurch ordnungsgemäß beendet werden kann.
Darin bash
gibt es eine Option namens , die, wenn sie gesetzt ist , beim Beenden/Abmelden zu SIGHUP ihrer untergeordneten Elemente huponexit
führt ;bash
Im interaktivenNicht-Login bash
In Instanzen, wie beispielsweise in einer bash
von erzeugten Instanz gnome-terminal
, wird diese Option ignoriert. Unabhängig davon, ob huponexit
sie gesetzt ist oder nicht, bash
werden die untergeordneten Elemente von bash
beim Beenden niemals von SIGHUPed.
Im interaktivenAnmeldung bash
Instanzen, wie etwa in einer bash
von erzeugten Instanz ssh
, wird diese Option nicht ignoriert (ist jedoch standardmäßig nicht gesetzt); wenn huponexit
gesetzt, bash
werden die untergeordneten Elemente von bash
beim Beenden/Abmelden von SIGHUPed; wenn huponexit
nicht gesetzt, werden die untergeordneten Elemente von beim Beenden/Abmelden bash
nicht von SIGHUPed ;bash
Wenn Sie also eine interaktive Anmeldeinstanz beenden/abmelden, wird die Shell im Allgemeinen nicht dazu führen, dass sie ihre untergeordneten Elemente SIGHUP, bash
es sei denn, die huponexit
Option ist festgelegt. Und wenn Sie eine interaktive Nicht-Anmeldeinstanz beenden/abmelden, wird bash
die Shell unabhängig davon nicht dazu führen, dass sie ihre untergeordneten Elemente SIGHUP.
Dies ist jedoch in diesem Fall irrelevant: using kill -9
sleep
bleibt trotzdem bestehen, da das Beenden des übergeordneten Prozesses ( bash
) diesem keine Chance lässt,irgendetwaszu Ersterem (also beispielsweise, wenn es sich bei der aktuellen bash
Instanz um eine Login- bash
Instanz handelte und die huponexit
Option gesetzt war, sie per SIGHUP durchzuführen).
Hinzu kommt, dass bash
ein SIGKILL-Signal, anders als andere Signale (wie ein an gesendetes SIGHUP-Signal), nie an die Kindprozesse eines Prozesses weitergegeben und daher sleep
nicht einmal beendet wird.
nohup
startet einen Prozess, der gegenüber SIGHUP-Signalen immun ist, was etwas anderes ist; es verhindert, dass der Prozess beim Empfang eines SIGHUP-Signals auflegt, das in diesem Fall von der interaktiven Anmeldeinstanz empfangen werden könnte, bash
falls die huponexit
Option gesetzt und die Shell beendet wurde; technisch gesehen verhindert also die Verwendung nohup
zum Starten eines Prozesses in einer interaktiven Anmeldeinstanz bash
mit huponexit
nicht gesetzter Option, dass der Prozess beim Empfang eines SIGHUP-Signals auflegt, aber das Beenden/Abmelden der Shell führt trotzdem nicht zu einem SIGHUP;
Wenn jedoch nohup
SIGHUP-Signale von der übergeordneten Shell verhindert werden müssen, gibt es im Allgemeinen keinen Grund, die kill -9
übergeordnete Methode nohup
der untergeordneten Methode vorzuziehen. Stattdessen sollte es umgekehrt sein.
Das Beenden des übergeordneten Elements mit der kill -9
Methode lässt diesem keine Chance, ordnungsgemäß zu beenden. Das Starten des untergeordneten Elements mit der nohup
Methode ermöglicht hingegen die Beendigung des übergeordneten Elements durch andere Signale, wie z. B. SIGHUP (um ein Beispiel zu nennen, das im Kontext eines untergeordneten Elements, das mit gestartet wurde, Sinn ergibt nohup
), wodurch ein ordnungsgemäßes Beenden ermöglicht wird.
Antwort2
bash
standardmäßigsendet beim Beenden kein HUP-Signal an untergeordnete Prozesse. Genauer gesagt (danke @kos), es tut es nie fürNicht-Login-Shells.
Sie können bash so konfigurieren, dass es dies fürLogin-ShellsSetzen Sie die Option huponexit
. Gehen Sie in einem Terminal wie folgt vor:
[romano:~] % bash -l
(dadurch wird eine neue „Login“-Shell gestartet)
romano@pern:~$ shopt -s huponexit
romano@pern:~$ sleep 1234 &
[1] 32202
romano@pern:~$ exit
logout
Prüfen Sie nun den sleep
Vorgang:
[romano:~] % ps augx | grep sleep
romano 32231 0.0 0.0 16000 2408 pts/11 S+ 15:23 0:00 grep sleep
... läuft nicht: Es hat das HUP-Signal empfangen und wurde wie gewünscht beendet.
Antwort3
Wenn
sleep
ich auf diese Weise überleben kann, bedeutet das, dass ich diese Methode anstelle einesnohup
Befehls verwenden kann?
kill -9
ist wirklich nicht der richtige Weg. Es ist, als würde man mit einer Waffe auf den Fernseher schießen, um ihn auszuschalten. Abgesehen von der komödiantischen Komponente hat es keinen Vorteil. Prozesse können nicht abfangen oder ignorieren SIGKILL
. Wenn Sie dem Prozess keine Chance geben, seine Arbeit zu beenden und aufzuräumen, hinterlässt er möglicherweise beschädigte Dateien (oder andere Zustände) und kann nicht erneut gestartet werden. kill -9
ist die letzte Hoffnung, wenn nichts anderes funktioniert.
Warum kann der Ruheprozess weiterlaufen, wenn ich mich abmelde und das Terminal geschlossen wird? Meiner Meinung nach wird beim Abmelden alles außer dem Daemon und dem Nohup-Programm beendet.
Was in Ihrem Fall passiert:
Der übergeordnete Prozess von sleep
ist die aktuell laufende bash
Shell. Wenn Sie kill -9
diese Bash ausführen, hat der Bash-Prozess keine Chance, eine SIGHUP
an einen seiner untergeordneten Prozesse zu senden, da SIGKILL
(die von gesendet wird kill -9
) vom Prozess nicht abgefangen werden kann. Der Sleep-Prozess läuft weiter. sleep wurde jetzt zu einemverwaister Prozess.
Der Init-Prozess (PID 1) führt einen Mechanismus namens Reparenting aus. Das bedeutet, dass der Init-Prozess nun zum übergeordneten Prozess dieses verwaisten Prozesses wird. Init ist eine Ausnahme, Prozesse können zu untergeordneten Prozessen werden, wenn es Prozesse sammelt, die ihren ursprünglichen übergeordneten Prozess verloren haben. Übrigens: Ein Daemon (wie sshd
) macht das, wenn er „in den Hintergrund geht“.
Wenn das nicht passieren würde, würde der verwaiste Prozess später (wenn er beendet ist) zu einem Zombie-Prozess werden. Das passiert, wenn waitpid()
nicht aufgerufen wird (eine Verantwortung des übergeordneten Prozesses, die nicht erfüllt werden kann, wenn dieser Prozess beendet wird). init ruft waitpid()
in einem bestimmten Intervall auf, um Zombie-Kindprozesse zu vermeiden.
Antwort4
Durch die Verwendung &
wird das Programm im Hintergrund ausgeführt. Um das Programm im Hintergrund anzuzeigen bg
, verwenden Sie den Befehl . Um es wieder im Vordergrund laufen zu lassen, führen Sie aus fg
.
Ja, es gibt viele Möglichkeiten, ein Programm weiterlaufen zu lassen, auch wenn das Hauptterminal beendet wird.