Was passiert mit Hintergrundjobs nach dem Beenden der Shell?

9

Von meinem Verständnis, Arbeitsplätze sind Pipelines von einer bestimmten Shell gestartet und Sie können diese Aufträge (verwalten fg, bgStrg-Z) aus dieser Schale. Ein Job kann aus mehreren Prozessen / Befehlen bestehen.

Meine Frage ist, was passiert mit diesen Jobs, wenn das Original mit der Shell beendet wird? Angenommen, huponexit ist nicht festgelegt, sodass Hintergrundprozesse nach dem Beenden der Shell weiter ausgeführt werden.

Angenommen, ich habe getan:

$ run.sh | grep 'abc' &
[1] job_id

Dann verlasse ich diese Shell. Ich werde eine neue Shell betreten und rennen jobsund offensichtlich nichts sehen. Aber ich kann ps aux | grep run.shdiesen Prozess ausführen und sehen, und ich werde auch ps aux | grep grepden Prozess zum grep 'abc'Ausführen ausführen und sehen .

Gibt es eine Möglichkeit, nur die Job-ID für die vollständige Pipeline abzurufen, damit ich sie auf einmal beenden kann, oder muss ich alle Prozesse getrennt von einer anderen Shell beenden, sobald ich die ursprüngliche Shell verlassen habe? (Letzteres habe ich ausprobiert und es funktioniert, aber es scheint mühsam, alle Prozesse im Auge zu behalten.)

user2193268
quelle

Antworten:

8

Wenn die Shell beendet wird, sendet sie möglicherweise das HUP-Signal an Hintergrundjobs, und dies kann dazu führen, dass diese beendet werden. Das SIGHUP-Signal wird nur gesendet, wenn die Shell selbst ein SIGHUP empfängt, dh nur, wenn das Terminal exitwegfällt (z. B. weil der Terminalemulatorprozess abbricht ) und nicht, wenn Sie die Shell normal verlassen (mit dem eingebauten oder durch Eingabe von Ctrl+ D). Siehe In welchen Fällen wird SIGHUP beim Abmelden nicht an einen Job gesendet? und Gibt es eine UNIX-Variante, bei der ein untergeordneter Prozess mit seinem übergeordneten Prozess stirbt? für mehr Details. In Bash können Sie die huponexitOption festlegen , dass SIGHUP bei einem normalen Exit auch an Hintergrundjobs gesendet wird. In ksh, bash und zsh anrufendisownBei einem Job wird es aus der Liste der Jobs entfernt, an die SIGHUP gesendet werden soll. Ein Prozess, der SIGHUP empfängt, kann das Signal ignorieren oder abfangen und stirbt dann nicht. Mit nohupwenn Sie ein Programm macht es immun gegen SIGHUP laufen.

Wenn der Prozess aufgrund eines möglichen SIGHUP nicht abgebrochen wird, bleibt er zurück. Es gibt nichts mehr, was es mit Jobnummern in der Shell in Verbindung bringen könnte.

Der Prozess kann immer noch abbrechen, wenn er versucht, auf das Terminal zuzugreifen, das Terminal jedoch nicht mehr existiert. Das hängt davon ab, wie das Programm auf ein nicht vorhandenes Terminal reagiert.

Wenn der Job mehrere Prozesse enthält (z. B. eine Pipeline), befinden sich alle diese Prozesse in einer Prozessgruppe . Prozessgruppen wurden genau erfunden, um den Begriff eines Shell-Jobs zu erfassen, der aus mehreren verwandten Prozessen besteht. Sie können Prozesse anzeigen, die nach Prozessgruppen gruppiert sind, indem Sie ihre Prozessgruppen-ID (PGID - normalerweise die Prozess-ID des ersten Prozesses in der Gruppe) anzeigen, z. B. ps lunter Linux oder so etwas wie ps -o pid,pgid,tty,etime,commportabel.

Sie können alle Prozesse in einer Gruppe beenden, indem Sie ein negatives Argument an übergeben kill. Wenn Sie beispielsweise festgestellt haben, dass die PGID für die Pipeline, die Sie beenden möchten, 1234 ist, können Sie sie mit beenden

kill -TERM -1234
Gilles 'SO - hör auf böse zu sein'
quelle
2

Im Allgemeinen laufen sie immer noch, aber Sie sollten nohup verwenden, wenn Sie vergessen oder Ihre Meinung geändert haben, verwenden Sie disown.

mike@mike-laptop4:~$ sleep 500
^Z
[1]+  Stopped                 sleep 500
mike@mike-laptop4:~$ bg
[1]+ sleep 500 &
mike@mike-laptop4:~$ jobs
[1]+  Running                 sleep 500 &
mike@mike-laptop4:~$ disown %1
mike@mike-laptop4:~$ jobs
mike@mike-laptop4:~$ 
mikejonesey
quelle
und um zu töten, können Sie die übergeordnete Bash mit ps -ef --forest überprüfen. Wenn die Bash Hintergrundfunktionen hat, müssen Sie diese möglicherweise auch töten
mikejonesey