Por que usar "nohup &" em vez de "exec &"

67

Eu sei que, nohupsendo um binário, pode ser alcançado a partir de qualquer shell. Mas o execbuilt-in provavelmente existe em todos os shell.

Existe um motivo para preferir um deles, ao outro?

loxaxs
fonte

Respostas:

113

O que é melhor, um peixe ou uma bicicleta? nohupe execfazer coisas diferentes.

execsubstitui o shell por outro programa. Usar execum simples trabalho em segundo plano não é útil: exec myprogram; more stuffsubstitui o shell por myprograme, portanto, não é executado more stuff, ao contrário do myprogram; more stuffque é executado more stuffquando myprogramtermina; mas exec myprogram & more stuffcomeça myprogramem segundo plano e depois é executado more stuff, exatamente como myprogram & more stuff.

nohupexecuta o programa específico com o sinal SIGHUP ignorado. Quando um terminal é fechado, o kernel envia o SIGHUP para o processo de controle naquele terminal (ou seja, o shell). O shell, por sua vez, envia SIGHUP para todos os trabalhos em execução em segundo plano. A execução de um trabalho nohupevita que ele seja eliminado dessa maneira se o terminal morrer (o que acontece, por exemplo, se você efetuou login remotamente e a conexão caiu, ou se você fechar o emulador de terminal).

nohuptambém redireciona a saída do programa para o arquivo nohup.out. Isso evita que o programa morra porque não é capaz de gravar na saída ou na saída de erro. Observe que nohupnão redireciona a entrada. Para desconectar totalmente um programa do terminal onde você o iniciou, use

nohup myprogram </dev/null >myprogram.log 2>&1 &
Gilles 'SO- parar de ser mau'
fonte
27
uma bicicleta> um peixe
Chris Jaynes
6
Eu peço desculpa mas não concordo. O peixe é obviamente um método superior de transporte, se puder ser implementado.
ESTE USUÁRIO PRECISA DE AJUDA
6
@THISUSERNEEDSHELP Mas uma bicicleta é melhor comida, com certeza?
Gilles 'SO- stop be evil'
3
@GypsyCosmonaut Depois de executar exec firefox, o shell não está mais em execução: foi substituído por firefox. Você pode pensar execem combinar sair de um programa e iniciar um novo, mas mantendo o mesmo ID do processo. O terminal continua funcionando porque nada disse para parar. Quando você sai mais tarde do Firefox, o firefoxprocesso termina. O terminal percebe que seu processo filho saiu e, portanto, sai por sua vez.
Gilles 'SO- stop be evil'
5
Dê a um homem um peixe e você o alimentará por um dia. Dê a um homem uma bicicleta e ele poderá levá-la ao supermercado e comprar peixe por toda a vida.
David
18

exec & => executa um processo como um processo em segundo plano, para que você possa continuar usando o mesmo terminal para outros trabalhos.

nohup => evita todos os SIGHUP (sinal de término) e continua a execução mesmo se o terminal estiver fechado.

execprocesso morre quando a SIGHUPé recebido, mas o nohupprocesso continua.

Ani Menon
fonte
11
Esta resposta parece estar correta. Como outras respostas acima dizem, normalmente execsubstitui o processo em execução, mas isso não parece acontecer quando você usa o &segundo plano para executar o comando exec'd. Nem no bash nem no zsh.
Dan Pritts 29/07
@DanPritts O que você quer dizer com isso não acontece? Um subprocesso em segundo plano é iniciado e, em seguida, substituído, então exec smth &é o mesmo que (exec smth) &, não é isso que está acontecendo?
Phk # 1/17
11
Quero dizer, não é executado no sentido em que você normalmente pensaria (substituindo o shell em execução atual) - apenas é executado como um processo em segundo plano. Eu acho que provavelmente é o mesmo que (exec smth) &. Mas eu não esperaria que fosse o mesmo - eu esperaria que fosse um erro de sintaxe, como você pode executar um processo (substituindo a si mesmo) e depois colocar em segundo plano o processo executado? Você não está mais lá para fazer isso.
Dan Pritts
2

O comando exec <command>interno do shell substitui o shell por <command>, nenhum novo processo, nenhum novo PID é criado. Após a conclusão <command>normal, seu terminal será fechado. Ao executá-lo em segundo plano, primeiro é criado um subshell, que é imediatamente substituído por <command>.

O nohup <command> comando será executado, <command>mas seguirá para o hangups (kill -s 1), portanto não será encerrado quando o shell, o terminal a partir do qual foi iniciado, estiver fechado. Ao executá-lo em segundo plano, primeiro é criado um subshell e o comando é executado em segundo plano, retornando você ao prompt.

No script, o efeito imediato é mais ou menos o mesmo, porém, <command>é iniciado pelo seu script e o script continuará sem aguardar o <command>início, o envio da saída ou a conclusão.

HBruijn
fonte
Eu também não tenho certeza sobre o que o exec faz. Quero dizer ... eu entendo o que deveria fazer, mas vejo apenas uma pequena diferença entre fazer script.sh &ou exec script.sh &. Nos dois casos, o comando é executado em um processo filho, não substitui o processo de chamada, consulte: paste.alacon.org/44474 (muito tempo para copiá-lo aqui em um comentário ...). O que estou fazendo errado?
Stéphane
2

Você não pode comparar nohupcom exec. Quando você executa um executável com nohup, o processo não será interrompido quando você fizer logout (sessão ssh); geralmente nohupé usado nicepara executar processos com uma prioridade mais baixa. O HUPsinal é, por convenção, a maneira como um terminal avisa processos dependentes de logout

user2660420
fonte