Perché usare "nohup &" anziché "exec &"


67

So che, nohupessendo un binario, può essere raggiunto da qualsiasi shell. Ma il execbuilt-in probabilmente esiste in ogni shell.

C'è un motivo per preferire uno di loro, all'altro?

Risposte:


113

Cosa c'è di meglio, un pesce o una bicicletta? nohupe execfare cose diverse.

execsostituisce la shell con un altro programma. L'uso execin un semplice lavoro in background non è utile: exec myprogram; more stuffsostituisce la shell con myprograme quindi non funziona more stuff, diversamente da myprogram; more stuffcome viene eseguito more stuffquando myprogramtermina; ma exec myprogram & more stuffinizia myprogramin background e poi viene eseguito more stuff, proprio come myprogram & more stuff.

nohupesegue il programma specifico con il segnale SIGHUP ignorato. Quando un terminale è chiuso, il kernel invia SIGHUP al processo di controllo in quel terminale (cioè la shell). La shell a sua volta invia SIGHUP a tutti i lavori in esecuzione in background. L'esecuzione di un lavoro nohupimpedisce che venga ucciso in questo modo se il terminale muore (cosa che accade ad es. Se si è effettuato l'accesso in remoto e la connessione si interrompe o se si chiude l'emulatore di terminale).

nohupreindirizza anche l'output del programma sul file nohup.out. Questo evita che il programma muoia perché non è in grado di scrivere sul suo output o output di errore. Si noti che nohupnon reindirizza l'input. Per disconnettere completamente un programma dal terminale in cui è stato avviato, utilizzare

nohup myprogram </dev/null >myprogram.log 2>&1 &

27
una bicicletta> un pesce
Chris Jaynes il

6
Mi permetto di dissentire. Il pesce è ovviamente un metodo di trasporto superiore se può essere implementato.
QUESTO UTENTE HA BISOGNO DI AIUTO

6
@THISUSERNEEDSHELP Ma una bicicletta è cibo migliore, sicuramente?
Gilles 'SO- smetti di essere malvagio' il

3
@GypsyCosmonaut Dopo aver eseguito exec firefox, la shell non è più in esecuzione: è stata sostituita da firefox. Puoi pensare di execcombinare l'uscita da un programma e avviarne uno nuovo, mantenendo lo stesso ID processo. Il terminale continua a funzionare perché nulla gli ha detto di fermarsi. Quando successivamente esci da Firefox, il firefoxprocesso termina. Il terminale nota che il suo processo figlio è uscito e quindi a sua volta esce.
Gilles 'SO- smetti di essere malvagio' il

5
Dai un pesce a un uomo e gli dai da mangiare per un giorno. Dai a un uomo una bicicletta e può andare al supermercato e comprare pesce per tutta la vita.
David

18

exec & => esegue un processo come processo in background in modo da poter continuare a utilizzare lo stesso terminale per altri lavori.

nohup => evita tutti i SIGHUP (segnale di terminazione) e continua l'esecuzione anche se il terminale è chiuso.

execil processo muore quando SIGHUPviene ricevuto un, ma il nohupprocesso continua.


1
Questa risposta sembra essere corretta. Come dicono altre risposte sopra, normalmente execsostituisce il processo in esecuzione, ma ciò non sembra accadere quando si usa &in background il comando exec'd. Né in bash né in zsh.
Dan Pritts,

@DanPritts Che cosa vuoi dire con ciò non accade? Un sottoprocesso in background viene avviato e quindi sostituito, quindi exec smth &è lo stesso di (exec smth) &quello che sta succedendo?
phk,

1
Voglio dire, non viene eseguito nel senso che normalmente si penserebbe (sostituendo l'attuale shell in esecuzione) - viene semplicemente eseguito come processo in background. Immagino che probabilmente sia lo stesso di (exec smth) &. Ma non mi aspetto che sia lo stesso - mi aspetto che sia un errore di sintassi, come puoi eseguire un processo (sostituendo te stesso) e quindi in background il processo exec? Non sei più lì per farlo.
Dan Pritts,

2

Il comando integrato exec <command>della shell sostituisce la shell con <command>, nessun nuovo processo, nessun nuovo PID viene creato. Dopo il completamento, <command>normalmente il tuo terminale si chiuderà. Eseguendolo prima in background, viene creata una subshell, che quindi viene immediatamente sostituita da <command>.

Il nohup <command> comando verrà eseguito <command>ma si immetterà nei blocchi (kill -s 1), quindi non verrà terminato quando la shell, il terminale da cui è stato avviato, viene chiusa. Eseguendolo prima in background, viene creata una subshell e il comando viene eseguito in background, restituendo al prompt.

Nello scripting l'effetto immediato è più o meno lo stesso, <command>viene avviato dallo script e lo script continuerà senza attendere <command>l'avvio, l'invio dell'output o il completamento.


Anch'io non sono sicuro di ciò che fa exec. Voglio dire ... capisco cosa dovrebbe fare ma posso vedere solo una piccola differenza tra fare script.sh &o exec script.sh &. In entrambi i casi il comando viene eseguito in un processo figlio, non sostituisce il processo di chiamata, vedere: paste.alacon.org/44474 (troppo tempo per copiarlo qui in un commento ...). Che cosa sto facendo di sbagliato?
Stéphane,

2

Non puoi confrontarti nohupcon exec. Quando si esegue un eseguibile con nohup, il processo non verrà interrotto al logout (sessione ssh); di solito nohupviene utilizzato niceper eseguire processi con una priorità inferiore. Il HUPsegnale è, per convenzione, il modo in cui un terminale avverte processi dipendenti di logout

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.