Warum läuft mein Prozess noch, nachdem ich mich abgemeldet habe?

Warum läuft mein Prozess noch, nachdem ich mich abgemeldet habe?

Nachdem ich mich über angemeldet habe ssh, gebe ich diesen Befehl ein bash:

sleep 50000000000000 &

Dann schalte ich kill -9den 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 sleepVorgang noch aktiv ist.

Frage: Warum kann der sleepProzess überleben, wenn ich mich abmelde und das Terminal geschlossen wird? Meiner Meinung nach nohupwird beim Abmelden alles außer Daemons und Programmen beendet. Wenn sleeper auf diese Weise überleben kann, bedeutet das, dass ich diese Methode anstelle des nohupBefehls verwenden kann?

Antwort1

Kurz gesagt:

Warum kann der sleepProzess überleben, wenn ich mich abmelde und das Terminal geschlossen wird? Meiner Meinung nach nohupwird beim Abmelden alles außer Daemons und Programmen beendet. Wenn sleeper auf diese Weise überleben kann, bedeutet das, dass ich diese Methode anstelle des nohupBefehls verwenden kann?

Sofern die bashvon erzeugte Instanz nicht sshüber die huponexitfestgelegte Option verfügt, wird kein Prozess beim Beenden/Abmelden auf irgendeine Weise beendet. Wenn die huponexitOption festgelegt ist, kill -9ist die Verwendung auf der Shell keine gute Alternative zur Verwendung nohupauf den untergeordneten Prozessen der Shell. Die Verwendung nohupauf 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, nohupda die Shell dadurch ordnungsgemäß beendet werden kann.


Darin bashgibt es eine Option namens , die, wenn sie gesetzt ist , beim Beenden/Abmelden zu SIGHUP ihrer untergeordneten Elemente huponexitführt ;bash

Im interaktivenNicht-Login bashIn Instanzen, wie beispielsweise in einer bashvon erzeugten Instanz gnome-terminal, wird diese Option ignoriert. Unabhängig davon, ob huponexitsie gesetzt ist oder nicht, bashwerden die untergeordneten Elemente von bashbeim Beenden niemals von SIGHUPed.

Im interaktivenAnmeldung bashInstanzen, wie etwa in einer bashvon erzeugten Instanz ssh, wird diese Option nicht ignoriert (ist jedoch standardmäßig nicht gesetzt); wenn huponexitgesetzt, bashwerden die untergeordneten Elemente von bashbeim Beenden/Abmelden von SIGHUPed; wenn huponexitnicht gesetzt, werden die untergeordneten Elemente von beim Beenden/Abmelden bashnicht 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, bashes sei denn, die huponexitOption ist festgelegt. Und wenn Sie eine interaktive Nicht-Anmeldeinstanz beenden/abmelden, wird bashdie Shell unabhängig davon nicht dazu führen, dass sie ihre untergeordneten Elemente SIGHUP.

Dies ist jedoch in diesem Fall irrelevant: using kill -9 sleepbleibt trotzdem bestehen, da das Beenden des übergeordneten Prozesses ( bash) diesem keine Chance lässt,irgendetwaszu Ersterem (also beispielsweise, wenn es sich bei der aktuellen bashInstanz um eine Login- bashInstanz handelte und die huponexitOption gesetzt war, sie per SIGHUP durchzuführen).

Hinzu kommt, dass bashein SIGKILL-Signal, anders als andere Signale (wie ein an gesendetes SIGHUP-Signal), nie an die Kindprozesse eines Prozesses weitergegeben und daher sleepnicht einmal beendet wird.

nohupstartet 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, bashfalls die huponexitOption gesetzt und die Shell beendet wurde; technisch gesehen verhindert also die Verwendung nohupzum Starten eines Prozesses in einer interaktiven Anmeldeinstanz bashmit huponexitnicht 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 nohupSIGHUP-Signale von der übergeordneten Shell verhindert werden müssen, gibt es im Allgemeinen keinen Grund, die kill -9übergeordnete Methode nohupder untergeordneten Methode vorzuziehen. Stattdessen sollte es umgekehrt sein.

Das Beenden des übergeordneten Elements mit der kill -9Methode lässt diesem keine Chance, ordnungsgemäß zu beenden. Das Starten des untergeordneten Elements mit der nohupMethode 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

bashstandardmäß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 sleepVorgang:

[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 sleepich auf diese Weise überleben kann, bedeutet das, dass ich diese Methode anstelle eines nohupBefehls verwenden kann?

kill -9ist 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 -9ist 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 sleepist die aktuell laufende bashShell. Wenn Sie kill -9diese Bash ausführen, hat der Bash-Prozess keine Chance, eine SIGHUPan 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.

verwandte Informationen