Primeiro, vamos ver o que acontece se um programa for iniciado a partir de um shell interativo (conectado a um terminal) sem &
(e sem nenhum redirecionamento). Então vamos supor que você acabou de digitar foo
:
- O processo executando
foo
é criado. - O processo herda stdin, stdout e stderr do shell. Portanto, ele também está conectado ao mesmo terminal.
- Se o shell receber um
SIGHUP
, ele também enviará umSIGHUP
para o processo (o que normalmente faz com que o processo termine). - Caso contrário, o shell aguarda (está bloqueado) até o processo terminar.
Agora, vamos ver o que acontece se você colocar o processo em segundo plano, ou seja, digite foo &
:
- O processo executando
foo
é criado. - O processo herda stdout / stderr do shell (portanto, ele ainda grava no terminal).
- O processo em princípio também herda stdin, mas assim que ele tenta ler de stdin, ele é interrompido.
- Ele é colocado na lista de tarefas em segundo plano que o shell gerencia, o que significa especialmente:
- Ele está listado com
jobs
e pode ser acessado usando%n
(onden
é o número da tarefa). - Ele pode ser transformado em um trabalho em primeiro plano usando
fg
. Nesse caso, ele continua como se você não tivesse usado&
(e, se ele foi interrompido devido à tentativa de leitura da entrada padrão, agora pode continuar a ler a partir do terminal). - Se o shell recebeu um
SIGHUP
, ele também envia umSIGHUP
para o processo. Dependendo do shell e possivelmente das opções definidas para o shell, ao finalizar o shell, ele também enviará umSIGHUP
para o processo.
- Ele está listado com
Agora, disown
remove o trabalho da lista de trabalhos do shell, portanto, todos os subpontos acima não se aplicam mais (incluindo o processo que está sendo enviado um SIGHUP
pelo shell). Entretanto, note que ainda está conectado ao terminal, portanto, se o terminal for destruído (o que pode acontecer se for um arquivo, como os criados por xterm
ou ssh
, e o programa de controle é encerrado, fechando o xterm ou encerrando a conexão SSH ), o programa falhará assim que ele tentar ler entrada padrão ou escreva para a saída padrão.
O que o nohup
faz, por outro lado, é separar efetivamente o processo do terminal:
- Fecha a entrada padrão (o programa não consegue ler nenhuma entrada, mesmo que seja executado em primeiro plano. Não é interrompido, mas receberá um código de erro ou
EOF
). - Ele redireciona a saída padrão e o erro padrão para o arquivo
nohup.out
, de modo que o programa não falhará para gravar na saída padrão se o terminal falhar, portanto, qualquer que seja o processo gravado, ele não será perdido. - Impede que o processo receba
SIGHUP
(daí o nome).
Observe que nohup
não remove o processo do controle de tarefa do shell e também não o coloca em segundo plano (mas como o trabalho foreground nohup
é mais ou menos inútil, você geralmente colocaria em segundo plano usando &
). Por exemplo, diferentemente de disown
, o shell ainda lhe dirá quando a tarefa nohup foi concluída (a menos que o shell seja terminado antes, é claro).
Então, para resumir:
-
&
coloca a tarefa em segundo plano, isto é, bloqueia a tentativa de ler a entrada e faz com que ela não espere sua conclusão. -
disown
remove o processo do controle de tarefa do shell, mas ainda o deixa conectado ao terminal. Um dos resultados é que o shell não envia umSIGHUP
. Obviamente, ele só pode ser aplicado a tarefas em segundo plano, porque você não pode inseri-lo quando um trabalho em primeiro plano está em execução. -
nohup
desconecta o processo do terminal, redireciona sua saída paranohup.out
e protege-o deSIGHUP
. Um dos efeitos (o nome) é que o processo não receberá nenhumSIGHUP
enviado. É completamente independente do controle do trabalho e pode, em princípio, ser usado também para trabalhos em primeiro plano (embora isso não seja muito útil).