Differenza tra nohup, disown e &


578

Quali sono le differenze tra

$ nohup foo

e

$ foo &

e

$ foo & 
$ disown

50
Aspetta, puoi rinnegare senza specificare un PID? Grande!
ripper234,

34
C'è anche foo &!che dovrebbe essere uguale a rinnegarlo fin dall'inizio.
user4514

26
Bash non supporta & !.
Jonas Kongslund,

20
foo & disownrinnegare immediatamente.
ctrl-alt-delor,

9
Mi piacerebbe vedere una menzione di setsid, e come si riferisce a disownenohup
YoungFrog

Risposte:


557

Diamo prima un'occhiata a cosa succede se un programma viene avviato da una shell interattiva (connessa a un terminale) senza &(e senza alcun reindirizzamento). Quindi supponiamo che tu abbia appena scritto foo:

  • fooViene creato il processo in esecuzione .
  • Il processo eredita stdin, stdout e stderr dalla shell. Pertanto è anche collegato allo stesso terminale.
  • Se la shell riceve a SIGHUP, invia anche SIGHUPa al processo (che normalmente causa l'interruzione del processo).
  • Altrimenti la shell attende (è bloccata) fino al termine del processo.

Ora, vediamo cosa succede se metti il ​​processo in background, ovvero digita foo &:

  • fooViene creato il processo in esecuzione .
  • Il processo eredita stdout / stderr dalla shell (quindi scrive ancora sul terminale).
  • Il processo in linea di principio eredita anche lo stdin, ma non appena tenta di leggere dallo stdin, viene interrotto.
  • Viene inserito nell'elenco dei processi in background gestiti dalla shell, il che significa in particolare:
    • È elencato con jobsed è possibile accedervi utilizzando %n(dove si ntrova il numero del lavoro).
    • Può essere trasformato in un lavoro in primo piano usando fg, nel qual caso continua come se non l'avresti usato &(e se fosse stato interrotto a causa del tentativo di leggere dallo standard input, ora può procedere a leggere dal terminale).
    • Se la shell ha ricevuto a SIGHUP, invia anche SIGHUPa al processo. A seconda della shell e possibilmente delle opzioni impostate per la shell, al termine della shell invierà anche una SIGHUPal processo.

Ora disownrimuove il lavoro dall'elenco dei lavori della shell, quindi tutti i punti di cui sopra non si applicano più (incluso il processo che viene inviato SIGHUPdalla shell). Tuttavia nota che è ancora collegato al terminale, quindi se il terminale viene distrutto (cosa che può accadere se fosse un pty, come quelli creati da xtermo ssh, e il programma di controllo viene chiuso, chiudendo l'xterm o terminando la connessione SSH ) , il programma fallirà non appena tenta di leggere dall'input standard o di scrivere nell'output standard.

Quello nohupche invece è separare efficacemente il processo dal terminale:

  • Chiude l'input standard (il programma non sarà in grado di leggere alcun input, anche se viene eseguito in primo piano. Non viene arrestato, ma riceverà un codice di errore o EOF).
  • Reindirizza l'output standard e l'errore standard sul file nohup.out, quindi il programma non fallirà per la scrittura sull'output standard se il terminale fallisce, quindi qualsiasi cosa il processo scriva non andrà persa.
  • Impedisce al processo di ricevere un SIGHUP(quindi il nome).

Si noti che nohupnon non rimuovere il processo dal controllo il lavoro del guscio e, inoltre, non metterlo in background (ma dato un primo piano nohupdi lavoro è più o meno inutili, devi generalmente messo in secondo piano utilizzando &). Ad esempio, a differenza di con disown, la shell ti dirà ancora quando il processo nohup è stato completato (a meno che la shell non sia stata terminata prima, ovviamente).

Quindi per riassumere:

  • & mette il lavoro in background, cioè lo blocca nel tentativo di leggere l'input e fa in modo che la shell non attenda il suo completamento.
  • disownrimuove il processo dal controllo del lavoro della shell, ma lo lascia comunque collegato al terminale. Uno dei risultati è che la shell non lo invierà a SIGHUP. Ovviamente, può essere applicato solo ai lavori in background, poiché non è possibile inserirlo quando è in esecuzione un lavoro in primo piano.
  • nohupdisconnette il processo dal terminale, reindirizza la sua uscita nohup.oute lo protegge da SIGHUP. Uno degli effetti (quello di denominazione) è che il processo non riceverà alcun messaggio inviato SIGHUP. È completamente indipendente dal controllo dei lavori e in linea di principio potrebbe essere utilizzato anche per i lavori in primo piano (anche se non è molto utile).

8
+1 Grazie. Cosa succede quando si usa disown, nohup e & together?
Tim

15
Se si utilizzano tutti e tre insieme, il processo è in esecuzione in background, viene rimosso dal controllo del lavoro della shell e viene effettivamente disconnesso dal terminale.
Celtschk,


1
qual è la differenza tra disown %1e disown -h %1? Il secondo continuerà come un normale lavoro (ma ignora il segnale HUP) fino all'uscita del terminale?
Schemacs

4
Forse vale la pena includere (foo&)subshell
jiggunjer il

169

L'utilizzo &causa l'esecuzione del programma in background, quindi verrà visualizzato un nuovo prompt della shell anziché bloccarlo fino alla fine del programma. nohupe disownsono in gran parte indipendenti; sopprimono i segnali SIGHUP (blocco) in modo che il programma non venga automaticamente ucciso quando il terminale di controllo viene chiuso. nohupfa questo all'inizio del lavoro. Se non si esegue nohupun lavoro all'inizio, è possibile utilizzare disownper modificare un lavoro in esecuzione; senza argomenti modifica il lavoro corrente, che è quello che era appena in background


10
Piccola differenza tra nohup e disown: il comando disown lo rimuoverà dall'elenco dei lavori; nohup no.
Shawn J. Goff,

191
nohuped disownentrambi si può dire di sopprimere SIGHUP, ma in modi diversi. nohupfa inizialmente ignorare il segnale al programma (il programma potrebbe cambiarlo). nohupcerca anche di far sì che il programma non abbia un terminale di controllo, in modo che non venga inviato SIGHUPdal kernel quando il terminale è chiuso. disownè puramente interno al guscio; fa sì che la shell non invii SIGHUPquando termina.
Gilles,

27
@Gilles, il tuo commento merita una risposta di se stesso.
lesmana,

5
Solo un chiarimento sul commento di @ ShawnJ.Goff relativo alla disownrimozione del lavoro dall'elenco dei lavori. Se non si specifica un'opzione, la rimuove dall'elenco dei lavori. Tuttavia , se si specifica l' -hopzione, ogni jobspec non viene rimosso dalla tabella. Invece, lo fa in modo che SIGHUPnon venga inviato al lavoro se la shell riceve un SIGHUP.
martedì

4
Giusto per chiarire, l'uso &non ti dà un terminale, si stacca stdindal processo e lo fa funzionare in background, ma entrambi stdouted stderrè ancora collegato all'attuale tty. Ciò significa che potresti ottenere il testo di diversi programmi mescolati insieme, il che può essere piuttosto fastidioso se lo fai gimp &e ricevi molti errori GTK + mentre cerchi di usare quel tty per qualcos'altro.
Frank,

8

Ecco la mia esperienza nel tentativo di eseguire soffice in background, seguendo un comando non terminante (ad es tail.). Per questo esempio userò sleep 100.

&

#!/bin/bash
/opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard &
sleep 100

Io vedo Soffice logs / premendo i Ctrl- Cfermate Soffice

nohup .. &

#!/bin/bash
nohup /opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard &
sleep 100

Io non vedo soffice logs / premendo i Ctrl- Cfermate Soffice

e rinnegare

#!/bin/bash
/opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard & disown
sleep 100

Io vedo Soffice logs / premendo i Ctrl- Cfermate Soffice

setsid .. &

#!/bin/bash
setsid /opt/libreoffice4.4/program/soffice -invisible -nofirststartwizard &
sleep 100

Io vedo Soffice logs / premendo Ctrl- Csoffice non si ferma

Per risparmiare spazio::
nohup setsid ..non mostra i registri / soffice NONCtrlC SI FERMA acceso -
nohup con & disownalla fine: non mostra i registri / soffice si accende Ctrl-C


2
Mentre apprezzo lo sforzo di menzionare setsid e mostrare cosa succede in quella situazione specifica, mi piacerebbe vedere una risposta più approfondita. In particolare la differenza e le somiglianze di ciascuna soluzione, sia visibili (cosa succede quando si chiude la shell o il terminale, dove va l'output, ...) che invisibili (come vengono fatte le cose sotto il cofano e le loro implicazioni). La risposta accettata è una buona base per questo.
YoungFrog,

1
@YoungFrog Sono d'accordo su questo!
Marinos Il

Per me, con nohup ⟨command⟩ & disownil processo creato non si ferma Ctrl+C.
k.stm,

@ k.stm Hai provato soffice? sofficeil comando sembra avere qualcosa di diverso. Quindi ho considerato di aggiungerlo qui come un'eccezione alla regola. ad es. quando si usa :, nohup .. &premendo Ctrl-cnormalmente non si arresta il comando, ma con sofficeesso lo fa. Aspetto che qualcuno lo calpesti e spieghi perché questo accade con il soffice :)
Marinos il

@MarinosAn Sì, l'ho fatto. Corsi nohup soffice &e premetti Ctrl+C. Non è successo niente, come previsto.
k.stm,
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.