Por que meu processo ainda está em execução após o logout?

8

Após o login através de ssh , eu digito este comando em bash :

sleep 50000000000000 &

Então, eu kill -9 o processo pai do processo sleep (por exemplo, bash ). Em seguida, a janela do terminal se desconecta simultaneamente.

Quando eu faço login novamente, descubro que o processo sleep ainda está ativo.

Pergunta : Por que o processo sleep pode sobreviver quando eu faço logout e o terminal é fechado? Na minha opinião, tudo, exceto daemons e nohup , serão mortos durante o logout. Se sleep puder sobreviver dessa maneira, isso significa que posso usar esse método em vez do comando nohup ?

    
por tom_cat 14.10.2015 / 08:25

5 respostas

4

Tl; dr:

Why can the sleep process survive when I log out and the terminal is closed? In my mind, everything except daemons and nohup programs will be killed during logout. If sleep can survive in this way, does it mean that I can use this method instead of the nohup command?

A menos que a instância bash gerada por ssh tenha a opção huponexit definida, nenhum processo será encerrado por qualquer média ao sair / sair e quando a opção huponexit for definida, usando kill -9 no shell não é uma boa alternativa ao uso de nohup nos processos filhos do shell; nohup nos processos filhos do shell ainda os protegerá de SIGHUPs não provenientes do shell e, mesmo quando isso não for importante, nohup ainda será o preferido, pois permite que o shell seja encerrado normalmente.

Em bash , há uma opção chamada huponexit , que, se definida, tornará bash SIGHUP seus filhos na saída / logout;

Em instâncias não-login bash interativas, como em bash instance gerada por gnome-terminal , essa opção é ignorada; se huponexit estiver definido ou não definido, os filhos de bash nunca serão SIGHUPped por bash ao sair;

Em instâncias de login bash interativas, como em uma instância de bash gerada por ssh , essa opção não é ignorada (no entanto, é desfeita por padrão); se huponexit for definido, os filhos de bash serão SIGHUPped por bash na saída / logout; se huponexit não estiver definido, os filhos de bash não serão SIGHUPped por bash na saída / logout;

Portanto, em geral, sair / sair de um login interativo bash instance, a menos que a opção huponexit esteja definida, não fará o shell SIGHUP ser seus filhos e sair / sair de um% de não-login interativobash instance não tornará o shell SIGHUP seus filhos independentemente;

Isto é, no entanto, irrelevante neste caso: usar kill -9 sleep sobreviverá independentemente, porque matar seu processo pai ( bash ) não deixará uma chance para o último fazer qualquer coisa para o primeiro (por exemplo, se a atual bash instância foi um login bash instance e a opção huponexit foi definida, para SIGHUP it).

Somando-se a isso, diferente de outros sinais (como um sinal SIGHUP enviado para bash ), um sinal SIGKILL nunca é propagado para os processos filhos de um processo, portanto sleep não é nem morto;

nohup inicia um processo imune a sinais SIGHUP, o que é algo diferente; ele impedirá que o processo seja interrompido após a recepção de um sinal SIGHUP, que neste caso poderia ser recebido pelo login interativo bash instance no caso de a opção huponexit ter sido definida e o shell ter saído; então, tecnicamente, usar nohup para iniciar um processo em um login interativo bash instance com a opção huponexit não configurada evitará que o processo seja interrompido após a recepção de um sinal SIGHUP, mas saindo / saindo do shell não será t SIGHUP independentemente,

Em geral, no entanto, quando nohup é necessário para impedir que sinais SIGHUP sejam enviados do shell pai, não há motivo para preferir o kill -9 no método pai ao nohup no método filho; em vez disso, deveria ser o oposto.

Matar o pai usando o método kill -9 não deixa uma chance para o pai sair normalmente, enquanto iniciar o filho usando o método nohup permite que o pai seja terminado por outros sinais, como SIGHUP (para faça um exemplo que faça sentido no contexto de um filho que começou a usar nohup ), que permite que ele saia normalmente.

    
por kos 14.10.2015 / 08:50
3

bash por padrão não envia o HUP sinal para processos filhos ao sair . Mais detalhadamente (obrigado @kos), ele nunca faz isso por shell sem login .

Você pode configurar o bash para fazer isso para login shells se defina a opção huponexit . Em um terminal, faça:

[romano:~] % bash -l

(isso inicia um novo shell de "login")

romano@pern:~$ shopt -s huponexit
romano@pern:~$ sleep 1234 &
[1] 32202
romano@pern:~$ exit
logout

Agora, verifique o processo sleep :

[romano:~] % ps augx | grep sleep
romano   32231  0.0  0.0  16000  2408 pts/11   S+   15:23   0:00 grep sleep

... não está em execução: recebeu o sinal HUP e saiu conforme solicitado.

    
por Rmano 14.10.2015 / 09:57
2

If sleep can survive in this way, if it means that I can use this method instead of nohup command?

kill -9 não é realmente o caminho que se deve seguir. É como atirar com uma arma na TV para desligá-lo. Além do componente cômico, não há vantagem. Os processos não podem capturar ou ignorar SIGKILL . Se você não der ao processo a chance de terminar o que está fazendo e limpar, pode deixar arquivos corrompidos (ou outro estado) por perto e não poderá iniciar novamente. kill -9 é a última esperança, quando nada mais funciona.

Why sleep process can survive when I logout and terminal is closed. In my mind, everything except daemon and nohup program will be killed when logout.

O que acontece no seu caso:

O processo pai de sleep é o bash shell em execução no momento. Quando você kill -9 desse bash, o processo bash não tem a chance de enviar um SIGHUP para qualquer um de seus processos filhos, porque SIGKILL (que é enviado por kill -9 ) não pode ser rastreado pelo processo. O processo de suspensão continua em execução. dormir agora se tornou um processo órfão .

O processo init (PID 1) faz um mecanismo chamado reparinging. Isso significa que o processo de inicialização agora se torna o pai desse processo órfão. O init é uma exceção, os processos podem se tornar seus filhos, pois coletam processos que perderam o processo pai original. Btw: Um daemon (como sshd ) faz isso quando "está em segundo plano".

Se isso não acontecesse, o processo órfão mais tarde (quando terminado) se tornaria um processo zumbi. Isto é o que acontece quando waitpid() não é chamado (uma responsabilidade do processo pai que não pode ser preenchida quando esse processo é morto). O init chama waitpid() em um intervall específico para evitar zumbis childs.

    
por chaos 14.10.2015 / 09:52
1

O & inicia o processo em segundo plano. Se você digitar ps -ef , verá que o ID do processo pai (PPID) do seu sono é seu bash. Em seguida, faça logout e faça login novamente. O processo permanecerá em execução após o logout. Depois de fazer o login pela segunda vez, você executará ps -ef novamente. Você verá que agora o pai do seu processo de suspensão será processado com o id "1". Isso é o init, o pai de todos os processos.

    
por nobody 14.10.2015 / 08:35
0

Usar & fará com que o programa seja executado como plano de fundo. Para ver o programa em segundo plano, use o comando bg e, para torná-lo novamente em primeiro plano, execute fg .

Sim, existem muitas maneiras de manter o programa em execução até mesmo o terminal principal foi encerrado.

    
por Aizuddin Zali 14.10.2015 / 08:35

Tags