`Disown -h` e` nohup` funcionam efetivamente da mesma forma?

18

disown

  • faz com que um shell não envie SIGHUP para seu trabalho renegado quando o shell termina e

  • remove o trabalho renegado do controle de trabalho do shell.

O primeiro é o resultado do segundo? Em outras palavras, se um processo iniciado a partir de um shell for removido do controle de trabalho do shell de alguma forma, o shell não enviará SIGHUP para o processo quando o shell terminar?

disown -h ainda mantém um processo sob o controle de trabalho de um shell. Isso significa que disown -hfaz com que um processo ainda receba o SIGHUP enviado do shell, mas configura a ação do SIGHUP pelo processo para "ignorar"? Isso soa semelhante a nohup.

$ sleep 123 & disown -h
[1] 26103
$ jobs
[1]+  Running                 sleep 123 &
$ fg 1
sleep 123
$ ^Z
[1]+  Stopped                 sleep 125
$ bg 1
[1]+ sleep 123 &
$ exit

$ ps aux | grep sleep
t        26103  0.0  0.0  14584   824 ?        S    15:19   0:00 sleep 123

Faça disown -he nohuptrabalhe efetivamente da mesma forma, se desconsiderarmos a diferença entre eles no uso de um terminal?

Obrigado.

Tim
fonte
Outra diferença não discutida aqui é que, se você não estiver usando nohup, precisará redirecionar stdin / stdout / stderr para longe do TTY (caso seu shell original esteja conectado a um). (OTOH, na verdade, considero essa prática melhor do que confiar em um padrão codificado egregado como ./nohup.out).
Charles Duffy

Respostas:

21

nohupe disown -hnão são exatamente a mesma coisa.

Com disown, um processo é removido da lista de trabalhos no shell interativo atual. A execução jobsapós o início de um processo em segundo plano e a execução disownnão mostrará esse processo como um trabalho no shell. Um trabalho renegado não receberá um HUPdo shell quando sair (mas consulte a observação no final).

Com disown -h, o trabalho não é removido da lista de trabalhos, mas o shell não enviaria um HUPsinal se saísse (mas veja a observação no final).

O nohuputilitário ignora o HUPsinal e inicia o utilitário especificado. O utilitário herda a máscara de sinal nohupe, portanto, também ignorará o HUPsinal. Quando o shell termina, o processo permanece como um processo filho de nohup(e nohupé reinserido como pai init).

A diferença é que o processo iniciado com nohupignora, HUPindependentemente de quem envia o sinal. Os processos deserdado não são apenas enviou um HUPsinal pelo shell , mas ainda pode ser enviado o sinal a partir por exemplo kill -s HUP <pid>e não irá ignorar isso.

Observe que HUPsomente é enviado para os trabalhos de um shell se

  • o shell é um shell de logon e a huponexitopção shell está definida ou
  • a própria concha recebe um HUPsinal.

Bits relevantes do bashmanual (minha ênfase):

SINAIS

[...]

O shell sai por padrão após o recebimento de aSIGHUP . Antes de sair, um shell interativo reenvia SIGHUPtodos os trabalhos, em execução ou interrompidos. Os trabalhos interrompidos são enviados SIGCONTpara garantir que eles recebam o SIGHUP. Para impedir que o shell envie o sinal para um trabalho específico, ele deve ser removido da tabela de trabalhos com o disownbuilt-in (veja SHELL BUILTIN COMMANDSabaixo) ou marcado para não receber o SIGHUP uso disown -h.

Se a huponexitopção shell tiver sido definida com shopt, bashenvia um SIGHUPpara todos os trabalhos quando um shell de logon interativo sai.

disown [-ar] [-h] [jobspec ... | pid ... ]

Sem opções, remova cada uma jobspecda tabela de trabalhos ativos. [...] Se a -hopção for dada, cada jobspecum não será removido da tabela, mas será marcado para que SIGHUPnão seja enviado ao trabalho se o shell receber aSIGHUP . [...]

Relacionado:

Kusalananda
fonte
Eu recebo o bash: disown: nohup: no such jobmesmo para sleepe 5de disown nohup sleep 5 &. O que você quis dizer com esse segundo comando da última frase?
Ruslan #
@Ruslan Sim, eu estou perdendo um &lá (e a ordem nohupe disowntambém estava errado). Obrigado. Irá atualizar agora.
Kusalananda
@ Tim Desculpe pela edição excessiva da resposta. Demorou um pouco para entender. Eu terminei agora.
Kusalananda
Obrigado. disowncria um shell não enviado SIGHUP para um filho removendo o filho da lista de trabalhos do shell. Como disown -hconseguir o mesmo?
Tim
4

Eles são diferentes:

  • Disown remove o trabalho da tabela de trabalhos ativos. Em seguida, continua com o trabalho atual. Com -h, o processo NÃO é enviado SIGHUP. Em vez disso, resta morrer com a concha que a contém, quando recebe um SIGHUP.

  • nohup ignora o HUP. Então, qualquer coisa que teria sido passada ao terminal pelo fechamento do processo será enviada para um arquivo nohup.out.

    nohup é definido pelo POSIX, enquanto não é negado.

Michael Prokopec
fonte
Como assim, "morra com a concha que a contém"? Matar um processo pai não mata por si só um filho. Os programas cujos terminais estão fechados geralmente morrem devido a falhas relacionadas a tentativas de interagir com um identificador de arquivo conectado ao PTY do terminal, mas se stdin / stdout / stderr for redirecionado para outro lugar, isso não acontecerá.
Charles Duffy