Warum "nohup &" anstelle von "exec &" verwenden?

67

Ich weiß, dass nohupes als Binärdatei von jeder Shell aus erreichbar ist. Aber das execeingebaute existiert wahrscheinlich in jeder Shell.

Gibt es einen Grund, den einen dem anderen vorzuziehen?

loxaxs
quelle

Antworten:

113

Was ist besser, ein Fisch oder ein Fahrrad? nohupund execverschiedene Dinge tun.

execErsetzt die Shell durch ein anderes Programm. Die Verwendung execin einem einfachen Hintergrundjob ist nicht sinnvoll: exec myprogram; more stuffErsetzt die Shell durch myprogramund wird nicht ausgeführt more stuff, im Gegensatz zu myprogram; more stuffder, die more stuffbeim myprogramBeenden ausgeführt wird. aber exec myprogram & more stufffängt myprogramim hintergrund an und läuft dann more stuffgenauso ab myprogram & more stuff.

nohupFührt das angegebene Programm mit ignoriertem SIGHUP-Signal aus. Wenn ein Terminal geschlossen wird, sendet der Kernel SIGHUP an den Steuerungsprozess in diesem Terminal (dh der Shell). Die Shell wiederum sendet SIGHUP an alle Jobs, die im Hintergrund ausgeführt werden. Das Ausführen eines Jobs mit nohupverhindert, dass er auf diese Weise beendet wird, wenn das Terminal abstürzt (was z. B. der Fall ist, wenn Sie remote angemeldet waren und die Verbindung getrennt wurde oder wenn Sie den Terminalemulator schließen).

nohupLeitet auch die Ausgabe des Programms in die Datei um nohup.out. Dies vermeidet, dass das Programm abstirbt, da es nicht in seine Ausgabe oder Fehlerausgabe schreiben kann. Beachten Sie, dass nohupdie Eingabe nicht umgeleitet wird. Um ein Programm vollständig von dem Terminal zu trennen, auf dem Sie es gestartet haben, verwenden Sie

nohup myprogram </dev/null >myprogram.log 2>&1 &
Gilles
quelle
27
ein Fahrrad> ein Fisch
Chris Jaynes
6
Ich bin anderer Ansicht. Fisch ist offensichtlich ein überlegenes Transportmittel, wenn es eingesetzt werden kann.
DIESER BENUTZER BRAUCHT HILFE
6
@THISUSERNEEDSHELP Aber ein Fahrrad ist doch besseres Essen?
Gilles
3
@GypsyCosmonaut Nachdem Sie ausgeführt haben exec firefox, wird die Shell nicht mehr ausgeführt: Sie wurde durch ersetzt firefox. Sie können sich vorstellen, dass Sie execdas Beenden eines Programms mit dem Starten eines neuen Programms kombinieren und dabei dieselbe Prozess-ID beibehalten. Das Terminal läuft weiter, weil es nicht angewiesen wurde anzuhalten. Wenn Sie Firefox später firefoxbeenden , wird der Prozess beendet. Das Terminal stellt fest, dass sein untergeordneter Prozess beendet wurde, und beendet sich daher.
Gilles
5
Gib einem Mann einen Fisch und du fütterst ihn für einen Tag. Geben Sie einem Mann ein Fahrrad und er kann damit zum Supermarkt fahren und ein Leben lang Fisch kaufen.
David
18

exec & => führt einen Prozess als Hintergrundprozess aus, sodass Sie dasselbe Terminal für andere Jobs verwenden können.

nohup => vermeidet jegliches SIGHUP (Beendigungssignal) und setzt die Ausführung fort, auch wenn Ihr Terminal geschlossen ist.

execProzess stirbt, wenn ein SIGHUPempfangen wird, aber der nohupProzess wird fortgesetzt.

Ani Menon
quelle
1
Diese Antwort scheint richtig zu sein. Wie andere Antworten oben sagen, execersetzt normalerweise den laufenden Prozess, aber das scheint nicht zu passieren, wenn Sie &den Befehl exec'd im Hintergrund ausführen. Weder in bash noch in zsh.
Dan Pritts
@DanPritts Was meinst du damit passiert nicht? Ein Hintergrund-Subprozess wird gestartet und dann ersetzt. Ist exec smth &das (exec smth) &nicht das, was gerade passiert?
phk
1
Ich meine, es wird nicht in dem Sinne ausgeführt, wie Sie es sich normalerweise vorstellen (anstelle der aktuell ausgeführten Shell) - es wird nur als Hintergrundprozess ausgeführt. Ich denke es ist wahrscheinlich dasselbe wie (exec smth) &. Aber ich würde nicht erwarten, dass es dasselbe ist - ich würde erwarten, dass es ein Syntaxfehler ist. Wie können Sie einen Prozess ausführen (indem Sie sich selbst ersetzen) und dann den ausgeführten Prozess im Hintergrund ausführen? Du bist nicht mehr da, um es zu tun.
Dan Pritts
2

Der eingebaute Shell-Befehl exec <command>ersetzt die Shell durch <command>, es wird kein neuer Prozess und keine neue PID erstellt. Nach Beendigung des <command>normalen Vorgangs wird Ihr Terminal geschlossen. Durch Ausführen im Hintergrund wird zunächst eine Subshell erstellt, die dann ebenfalls sofort durch ersetzt wird <command>.

Der nohup <command> Befehl wird ausgeführt <command>, bleibt jedoch hängen (kill -s 1), sodass er nicht beendet wird, wenn die Shell, von der aus er gestartet wurde, geschlossen wird. Wenn Sie es zuerst im Hintergrund ausführen, wird eine Subshell erstellt, und der Befehl wird im Hintergrund ausgeführt, sodass Sie zur Eingabeaufforderung zurückkehren.

Beim Skripten ist der unmittelbare Effekt jedoch mehr oder weniger derselbe, er <command>wird von Ihrem Skript gestartet und das Skript wird fortgesetzt, ohne darauf zu warten, dass <command>es gestartet, ausgegeben oder abgeschlossen wird.

HBruijn
quelle
Ich bin mir auch nicht sicher, was exec tut. Ich meine ... ich verstehe, was es tun soll, aber ich kann nur einen kleinen Unterschied zwischen tun script.sh &oder sehen exec script.sh &. In beiden Fällen wird der Befehl in einem untergeordneten Prozess ausgeführt und ersetzt nicht den aufrufenden Prozess. Siehe paste.alacon.org/44474 (zu lang, um ihn hier in einem Kommentar zu kopieren ...). Was mache ich falsch?
Stéphane
2

Sie können nicht vergleichen nohupmit exec. Wenn Sie eine ausführbare Datei mit ausführen nohup, wird der Prozess beim Abmelden (ssh-Sitzung) nicht abgebrochen. wird normalerweise nohupverwendet nice, um Prozesse mit einer niedrigeren Priorität auszuführen. Das HUPSignal ist gemäß Konvention die Art und Weise, wie ein Terminal abhängige Abmeldeprozesse warnt

user2660420
quelle