Funktionieren "disown -h" und "nohup" effektiv gleich?

18

disown

  • bewirkt, dass eine Shell SIGHUP nicht an ihren nicht freigegebenen Job sendet, wenn die Shell beendet wird, und

  • Entfernt den abgelehnten Job aus der Jobsteuerung der Shell.

Ist das erste das Ergebnis des zweiten? Mit anderen Worten, wenn ein von einer Shell gestarteter Prozess auf irgendeine Weise aus der Jobsteuerung der Shell entfernt wird, sendet die Shell dann nicht SIGHUP an den Prozess, wenn die Shell beendet wird?

disown -h behält einen Prozess weiterhin unter der Job-Kontrolle einer Shell. Bedeutet das, dass disown -hein Prozess weiterhin SIGHUP von der Shell empfängt, aber die Aktion von SIGHUP durch den Prozess so einrichtet, dass sie "ignoriert" wird? Das klingt ähnlich wie nohup.

$ sleep 123 & disown -h
[1] 26103
$ jobs
[1]+  Running                 sleep 123 &
$ fg 1
sleep 123
$ ^Z
[1]+  Stopped                 sleep 125
$ bg 1
[1]+ sleep 123 &
$ exit

$ ps aux | grep sleep
t        26103  0.0  0.0  14584   824 ?        S    15:19   0:00 sleep 123

Funktionieren disown -hund nohuparbeiten Sie effektiv gleich, wenn wir die Unterschiede bei der Verwendung eines Terminals außer Acht lassen?

Vielen Dank.

Tim
quelle
Ein weiterer Unterschied, der hier nicht erörtert wird, besteht darin, dass Sie nohupstdin / stdout / stderr (falls Ihre ursprüngliche Shell mit einer solchen verbunden ist) selbst umleiten müssen , wenn Sie sie nicht verwenden . (OTOH, ich halte das eigentlich für eine bessere Übung, als mich auf einen ungeheuren, hartkodierten Standard zu verlassen, wie ./nohup.out).
Charles Duffy

Antworten:

21

nohupund disown -hsind nicht genau dasselbe.

Mit disownwird ein Prozess aus der Liste der Jobs in der aktuellen interaktiven Shell entfernt. Laufen jobsnach einem Hintergrundprozess starten und laufen disownwird als Job in der Schale nicht diesen Prozess zeigen. Ein abgelehnter Job erhält beim Beenden kein HUPvon der Shell (siehe Hinweis am Ende).

Mit disown -hwird der Job nicht aus der Jobliste entfernt, aber die Shell sendet beim Beenden kein HUPSignal (siehe Hinweis am Ende).

Das nohupDienstprogramm ignoriert das HUPSignal und startet das angegebene Dienstprogramm. Das Dienstprogramm erbt die Signalmaske von nohupund ignoriert daher auch das HUPSignal. Wenn die Shell beendet wird, bleibt der Prozess ein untergeordneter Prozess von nohup(und nohupwird übergeordnet init).

Der Unterschied besteht darin, dass der Prozess mit nohupIgnorieren gestartet wird, HUPunabhängig davon, wer das Signal sendet. Die verleugnete Prozesse werden einfach nicht gesendet ein HUPSignal von der Schale , kann aber immer noch das Signal von zB gesendet werden kill -s HUP <pid>und wird dies nicht ignorieren.

Beachten Sie, dass HUPnur dann an die Jobs einer Shell gesendet wird, wenn

  • die Shell ist eine Login-Shell und die huponexitShell-Option ist gesetzt, oder
  • Die Shell selbst empfängt ein HUPSignal.

Relevante Teile aus dem bashHandbuch (mein Schwerpunkt):

SIGNALE

[...]

Die Shell wird standardmäßig mit Erhalt von a beendetSIGHUP . Vor dem Beenden sendet eine interaktive Shell die aktuellen SIGHUPoder angehaltenen Jobs erneut an alle Jobs. Angehaltene Jobs werden gesendet, SIGCONTum sicherzustellen, dass sie die Nachricht erhalten SIGHUP. Um zu verhindern, dass die Shell das Signal an einen bestimmten Job sendet, sollte dieser mit dem disowneingebauten Befehl (siehe SHELL BUILTIN COMMANDSunten) aus der Jobtabelle entfernt oder als nicht empfangend markiert SIGHUP werden disown -h.

Wenn die huponexitShell - Option mit gesetzt wurde shopt, bashsendet ein SIGHUPfür alle Jobs , wenn eine interaktive Login - Shell beendet.

disown [-ar] [-h] [jobspec ... | pid ... ]

Entfernen Sie alle jobspecJobs ohne Optionen aus der Tabelle der aktiven Jobs. [...] Wenn die -hMöglichkeit gegeben wird, die jeweils jobspecwird nicht entfernt von dem Tisch, aber ist markiert , so dass SIGHUPnicht auf den Auftrag gesendet wird , wenn die Schale a erhältSIGHUP . [...]

Verbunden:

Kusalananda
quelle
Ich bekomme bash: disown: nohup: no such jobund auch für sleepund 5von disown nohup sleep 5 &. Was meintest du mit dem zweiten Befehl aus dem letzten Satz?
Ruslan
@ Ruslan Ja da fehlt mir ein &(und die Reihenfolge von nohupund disownwar auch falsch). Vielen Dank. Wird jetzt aktualisiert.
Kusalananda
@Tim Entschuldigung für die übermäßige Bearbeitung der Antwort. Es dauerte eine Weile, bis ich mich daran gewöhnt hatte. Ich bin jetzt fertig.
Kusalananda
Vielen Dank. disownSorgt dafür, dass eine Shell kein SIGHUP an ein untergeordnetes Objekt sendet, indem das untergeordnete Objekt aus der Jobliste der Shell entfernt wird. Wie wird disown -hdasselbe erreicht?
Tim
4

Sie sind anders:

  • disown entfernt den Job aus der aktiven Jobtabelle. Fahren Sie dann mit dem aktuellen Job fort. Mit -h wird der Prozess NICHT SIGHUP gesendet. Es wird stattdessen mit der Shell, die es enthält, sterben gelassen, wenn es ein SIGHUP erhält.

  • nohup ignoriert das HUP. Dann wird alles, was beim Schließen des Prozesses an das Terminal übergeben worden wäre, in eine Datei verschoben nohup.out.

    nohup wird von POSIX definiert, nicht jedoch disown.

Michael Prokopec
quelle
Was meinst du mit "sterben mit der Shell, die es enthält"? Das Töten eines Elternprozesses bringt an und für sich kein Kind um. Programme, deren Terminals geschlossen sind, sterben in der Regel aufgrund von Fehlern im Zusammenhang mit dem Versuch, mit einem an das PTY des Terminals angehängten Datei-Handle zu interagieren. Wenn jedoch stdin / stdout / stderr an eine andere Stelle umgeleitet wird, geschieht dies nicht.
Charles Duffy,