Vamos primeiro 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 em execução
foo
é criado.
- O processo herda stdin, stdout e stderr do shell. Portanto, também está conectado ao mesmo terminal.
- Se o shell receber um
SIGHUP
, ele também enviará um SIGHUP
ao processo (o que normalmente causa o término do processo).
- Caso contrário, o shell aguarda (está bloqueado) até o processo terminar.
Agora, vejamos o que acontece se você colocar o processo em segundo plano, ou seja, digite foo &
:
- O processo em execução
foo
é criado.
- O processo herda stdout / stderr do shell (então ele ainda grava no terminal).
- O processo em princípio também herda stdin, mas assim que tenta ler a partir de stdin, ele é interrompido.
- Ele é colocado na lista de trabalhos em segundo plano que o shell gerencia, o que significa especialmente:
- Ele está listado
jobs
e pode ser acessado usando %n
(onde n
está o número do trabalho).
- Ele pode ser transformado em um trabalho em primeiro plano
fg
, caso em que continua como se você não o tivesse usado &
(e se foi interrompido por tentar ler da entrada padrão, agora pode prosseguir para a leitura no terminal).
- Se o shell recebeu um
SIGHUP
, ele também envia um SIGHUP
para o processo. Dependendo do shell e, possivelmente, das opções definidas para o shell, ao finalizar o shell, ele também enviará um SIGHUP
para o processo.
Agora, disown
o trabalho é removido da lista de trabalhos do shell, para que todos os subpontos acima não se apliquem mais (incluindo o processo enviado SIGHUP
pelo shell). No entanto, observe que ele ainda está conectado ao terminal, portanto, se o terminal for destruído (o que pode acontecer se for um pty, como os criados por xterm
ou ssh
, e o programa de controle for encerrado, feche o xterm ou encerre a conexão SSH ) , o programa falhará assim que tentar ler da entrada padrão ou gravar na saída padrão.
O nohup
que, por outro lado, é separar efetivamente o processo do terminal:
- Ele fecha a entrada padrão (o programa não poderá ler nenhuma entrada, mesmo que seja executado em primeiro plano. Não for 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
, para que o programa não falhe na gravação na saída padrão se o terminal falhar, para que o processo de gravação não seja perdido.
- Impede que o processo receba um
SIGHUP
(assim, o nome).
Note-se que nohup
se não remover o processo de controle de tarefas do shell e também não colocá-lo em segundo plano (mas desde um primeiro plano nohup
de trabalho é mais ou menos inútil, você geralmente colocá-lo em segundo plano usando &
). Por exemplo, diferentemente de disown
, o shell ainda informa quando o trabalho de nohup foi concluído (a menos que o shell seja encerrado antes, é claro).
Então, para resumir:
&
coloca o trabalho em segundo plano, ou seja, impede a tentativa de ler a entrada e faz com que o shell não aguarde sua conclusão.
disown
remove o processo do controle de trabalho do shell, mas ainda o deixa conectado ao terminal. Um dos resultados é que o shell não o envia a SIGHUP
. Obviamente, ele só pode ser aplicado a trabalhos 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 nohup.out
e a protege SIGHUP
. Um dos efeitos (o de nomeação) é que o processo não receberá nenhum envio SIGHUP
. É 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).