
Meinem Verständnis nach,Jobs sind Pipelinesvon einer bestimmten Shell aus gestartet werden und Sie können diese Jobs ( fg
, bg
, Strg-Z) von dieser Shell aus verwalten. Ein Job kann aus mehreren Prozessen/Befehlen bestehen.
Meine Frage ist, was mit diesen Jobs passiert, wenn die ursprüngliche, enthaltene Shell beendet wird. Angenommen, huponexit ist nicht festgelegt, sodass Hintergrundprozesse nach dem Beenden der Shell weiter ausgeführt werden.
Angenommen, ich habe Folgendes getan:
$ run.sh | grep 'abc' &
[1] job_id
Dann verlasse ich diese Shell. Ich gehe in eine neue Shell und führe aus jobs
und sehe offensichtlich nichts. Aber ich kann ps aux | grep run.sh
diesen Prozess ausführen und sehen, wie er ausgeführt wird, und ich kann auch ps aux | grep grep
den Prozess ausführen und sehen, wie grep 'abc'
er ausgeführt wird.
Gibt es eine Möglichkeit, nur die Job-ID für die gesamte Pipeline abzurufen, sodass ich sie auf einmal beenden kann, oder muss ich alle Prozesse einzeln von einer anderen Shell aus beenden, nachdem ich die ursprüngliche Shell verlassen habe? (Ich habe Letzteres versucht und es funktioniert, aber es scheint mühsam, den Überblick über alle Prozesse zu behalten.)
Antwort1
Wenn die Shell beendet wird, sendet sie möglicherweise das HUP-Signal an Hintergrundjobs, was dazu führen kann, dass diese beendet werden. Das SIGHUP-Signal wird nur gesendet, wenn die Shell selbst ein SIGHUP empfängt, also nur, wenn das Terminal verschwindet (z. B. weil der Terminalemulatorprozess abstürzt) und nicht, wenn Sie die Shell normal beenden (mit dem exit
integrierten Befehl oder durch Eingabe von Ctrl+ D). SieheIn welchen Fällen wird SIGHUP beim Abmelden nicht an einen Job gesendet?UndGibt es eine UNIX-Variante, bei der ein untergeordneter Prozess zusammen mit seinem übergeordneten Prozess beendet wird?für weitere Einzelheiten. In Bash können Sie die huponexit
Option festlegen, bei einem normalen Beenden auch SIGHUP an Hintergrundjobs zu senden. In Ksh, Bash und Zsh disown
wird ein Job durch Aufrufen aus der Liste der Jobs entfernt, an die SIGHUP gesendet wird. Ein Prozess, der SIGHUP empfängt, kann das Signal ignorieren oder abfangen und wird dann nicht beendet. Die Verwendung von nohup
beim Ausführen eines Programms macht es gegen SIGHUP immun.
Wenn der Prozess nicht durch ein mögliches SIGHUP beendet wird, bleibt er bestehen. Es gibt nichts mehr, was ihn in der Shell mit Jobnummern in Verbindung bringt.
Der Prozess kann immer noch abstürzen, wenn er versucht, auf das Terminal zuzugreifen, das Terminal aber 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), dann sind alle diese Prozesse in einemProzessgruppe. Prozessgruppen wurden genau deshalb erfunden, um das Konzept eines Shell-Jobs zu erfassen, der aus mehreren verwandten Prozessen besteht. Sie können Prozesse nach Prozessgruppen gruppiert anzeigen, indem Sie ihre Prozessgruppen-ID (PGID – normalerweise die Prozess-ID des ersten Prozesses in der Gruppe) anzeigen, z. B. unter ps l
Linux oder so ähnlich ps -o pid,pgid,tty,etime,comm
portabel.
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
Antwort2
Im Allgemeinen laufen sie noch, aber Sie sollten nohup verwenden. Wenn Sie es vergessen haben oder es sich anders überlegt 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:~$