Por que meu processo ainda está em execução depois que eu saio?

Por que meu processo ainda está em execução depois que eu saio?

Depois de fazer login ssh, digito este comando bash:

sleep 50000000000000 &

Então eu kill -9o sleepprocesso pai do processo (ou seja, bash). Então a janela do terminal se desconecta simultaneamente.

Quando faço login novamente, descubro que o sleepprocesso ainda está ativo.

Pergunta: Por que o sleepprocesso pode sobreviver quando eu saio e o terminal é fechado? Na minha opinião, tudo, exceto daemons e nohupprogramas, será eliminado durante o logout. Se sleeppuder sobreviver dessa forma, isso significa que posso usar esse método em vez do nohupcomando?

Responder1

dr:

Por que o sleepprocesso pode sobreviver quando eu saio e o terminal é fechado? Na minha opinião, tudo, exceto daemons e nohupprogramas, será eliminado durante o logout. Se sleeppuder sobreviver dessa forma, isso significa que posso usar esse método em vez do nohupcomando?

A menos que a bashinstância gerada por sshtenha a huponexitopção definida, nenhum processo será encerrado de forma alguma ao sair/logout, e quando a huponexitopção for definida, usar kill -9no shell não é uma boa alternativa para usar nohupnos processos filhos do shell; nohupnos processos filhos do shell ainda os protegerá de SIGHUPs que não vêm do shell, e mesmo quando isso não for importante nohupainda é preferível porque permite que o shell seja encerrado normalmente.


Existe bashuma opção chamada huponexit, que se definida tornará basho SIGHUP seu filho ao sair/logout;

Em interativosem login bashinstâncias, como em uma bashinstância gerada por gnome-terminal, esta opção é ignorada; esteja huponexitdefinido ou não, bashos filhos de nunca serão SIGHUPped na bashsaída;

Em interativoConecte-se bashinstâncias, como em uma bashinstância gerada por ssh, esta opção não é ignorada (no entanto, ela não está definida por padrão); se huponexitestiver definido, bashos filhos de serão SIGHUPped bashao sair/logout; se huponexitnão estiver definido, bashos filhos de 's não serão SIGHUPped bashao sair/logout;

Portanto, em geral, sair/efetuar logout de uma bashinstância de login interativa, a menos que a huponexitopção esteja definida, não tornará o shell SIGHUP seu filho, e sair/efetuar logout de uma bashinstância interativa sem login não tornará o shell SIGHUP seu filho sem considerar;

Isto é, no entanto, irrelevante neste caso: using kill -9 sleepsobreviverá independentemente, porque matar seu processo pai ( bash) não deixará chance para o último fazer issoqualquer coisapara o primeiro (ou seja, por exemplo, se a bashinstância atual era uma bashinstância de login e a huponexitopção foi definida, para SIGHUP).

Além disso, ao contrário de outros sinais (como um sinal SIGHUP enviado para bash), um sinal SIGKILL nunca é propagado para os processos filhos de um processo e, portanto, sleepnem mesmo é eliminado;

nohupinicia um processo imune aos sinais SIGHUP, o que é algo diferente; evitará que o processo seja interrompido ao receber um sinal SIGHUP, que neste caso poderia ser recebido pela bashinstância de login interativo caso a huponexitopção fosse definida e o shell fosse encerrado; portanto, tecnicamente, usar nohuppara iniciar um processo em uma bashinstância de login interativa com a huponexitopção não definida impedirá que o processo seja interrompido após a recepção de um sinal SIGHUP, mas sair/sair do shell não o SIGHUP de qualquer maneira;

Em geral, porém, quando nohupé necessário evitar que sinais SIGHUP venham do shell pai, não há razão para preferir o kill -9método on the parent ao nohupmétodo on the child; em vez disso, deveria ser o oposto.

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

Responder2

bashpor padrãonão envia o sinal HUP para processos filhos ao sair. Mais detalhadamente (obrigado @kos), isso nunca aconteceshells sem login.

Você pode configurar o bash para fazer issoshells de loginse definir 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 sleepprocesso:

[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.

Responder3

Se sleepposso sobreviver desta forma, se isso significa que posso usar este método em vez do nohupcomando?

kill -9realmente não é o caminho que se deve seguir. É como atirar com uma arma na TV para desligá-la. 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 limpá-lo, ele poderá deixar arquivos corrompidos (ou outro estado) e não será possível recomeçar. kill -9é a última esperança, quando nada mais funciona.


Por que o processo de suspensão pode sobreviver quando eu saio e o terminal é fechado. Na minha opinião, tudo, exceto o daemon e o programa nohup, será eliminado ao sair.

O que acontece no seu caso:

O processo pai sleepé o shell atualmente em execução bash. Quando você kill -9faz esse bash, o processo bash não tem a chance de enviar um SIGHUPpara nenhum de seus processos filhos, porque SIGKILL(que é enviado por kill -9) não é capturável pelo processo. O processo de suspensão continua em execução. dormir agora se tornou umprocesso órfão.

O processo init (PID 1) executa um mecanismo chamado reparenting. Isso significa que o processo init agora se torna o pai desse processo órfão. init é uma exceção, os processos podem se tornar filhos, pois coleta processos que perderam seu processo pai original. A propósito: um daemon (como sshd) faz isso quando "está em segundo plano".

Se isso não acontecesse, o processo órfão mais tarde (quando concluído) se tornaria um processo zumbi. Isto é o que acontece quando waitpid()não é chamado (uma responsabilidade do processo pai que não pode ser cumprida quando esse processo foi eliminado). init chama waitpid()em um intervalo específico para evitar filhos zumbis.

Responder4

O uso &fará com que o programa seja executado em segundo plano. Para ver o programa em segundo plano, use bgo comando e, para fazê-lo rodar em primeiro plano novamente, execute fg.

Sim, há muitas maneiras de manter o programa em execução mesmo com a saída do terminal principal.

informação relacionada