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

10

Após o login ssh, digite este comando bash:

sleep 50000000000000 &

Em seguida, kill -9o sleepprocesso pai do processo (isto é, bash). Então a janela do terminal se desconecta simultaneamente.

Ao efetuar login novamente, percebo 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á morto durante o logout. Se sleeppuder sobreviver dessa maneira, isso significa que eu posso usar esse método em vez do nohupcomando?

tom_cat
fonte
3
&colocará o processo em segundo plano (como daemon) e continuará sendo executado mesmo que você esteja desconectado.
Aizuddin Zali # 14/15

Respostas:

6

Tl; dr:

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

A menos que a bashinstância gerada sshtenha a huponexitopção definida, nenhum processo será encerrado por qualquer meio ao sair / sair e, quando a huponexitopção for definida, o uso kill -9no shell não será uma boa alternativa ao uso nohupnos processos filhos do shell; nohupnos processos filhos do shell ainda os protegerão de SIGHUPs que não saem do shell, e mesmo quando isso não nohupfor importante, ainda será o preferido, pois permite que o shell seja finalizado normalmente.


Em bashhá uma opção chamada huponexit, que se conjunto vai fazer bashSIGHUP seus filhos ao sair / logout;

Em instâncias interativas de não logon bash , como em uma bashinstância gerada por gnome-terminal, essa opção é ignorada; se huponexitestá definido ou não, bashos filhos de SUNUPUP nunca serão ASSOCIADOS bashao sair;

Nas instâncias de logon interativo bash, como em uma bashinstância gerada por ssh, essa opção não é ignorada (no entanto, é desativada por padrão); se huponexitfor definido, bashos filhos de SIGHUP serão buscados bashao sair / sair; se não estiver definido huponexit, bashos filhos de SIGHUPped não serão encontrados bashapós a saída / logout;

Portanto, em geral, sair / sair de uma bashinstância de logon interativo , a menos que a huponexitopção esteja definida, não tornará o shell SIGHUP seus filhos e sair / sair de uma bashinstância de não-logon interativo não fará o shell SIGHUP seus filhos independentemente;

Isso é, no entanto, irrelevante neste caso: o uso kill -9 sleepsobreviverá independentemente, porque matar o processo pai ( bash) não permitirá que o último faça algo com o anterior (por exemplo, se a bashinstância atual for uma bashinstância de login) e a huponexitopção foi configurada para SIGHUP it).

Além disso, diferentemente de outros sinais (como um sinal SIGHUP enviado para bash), um sinal SIGKILL nunca é propagado para os processos filhos de um processo, portanto, sleepnem é morto;

nohupinicia um processo imune aos sinais SIGHUP, que é algo diferente; impedirá que o processo seja interrompido com a recepção de um sinal SIGHUP, que nesse caso pode ser recebido pela bashinstância de logon interativo, caso a huponexitopção tenha sido definida e o shell seja encerrado; portanto, tecnicamente, o uso nohuppara iniciar um processo em uma bashinstância de logon interativo com a huponexitopção desabilitada impedirá que o processo seja interrompido na recepção de um sinal SIGHUP, mas sair / sair do shell não será SIGHUP independentemente;

No entanto, em geral, quando nohupé necessário para impedir que sinais SIGHUP sejam provenientes do shell pai, não há motivo para preferir o kill -9método on parent ao método nohupon child; em vez disso, deve ser o oposto.

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

kos
fonte
Em outras palavras, se eu tiver um script que foi colocado em segundo plano, ele continuará sendo executado mesmo se eu matar o processo pai, por exemplo, meu shell, certo? qual seria uma maneira de matar esse script?
Sergiy Kolodyazhnyy 14/10
@Serg Se você possui o PID, basta matar o PID; se você não armazenou o PID, mas pode identificar o processo pelo nome dele, ps -e | grep processdeve listar os processos junto com o PID (ou melhor, apenas pgrep -x processse tiver certeza de que coincide com esse processo único e não com coisas não esperadas); o problema é que quando você mata um processo com kill -9as suas crianças se possuído por upstart, daí seu PPID original é perdido e seu PPID muda para arrivista do PID, tornando-os irreconhecíveis (AFAIK), mas para o seu nome ou PID
kos
@kos Sob que condição nohupfalhará para impedir que um processo seja interrompido ao receber um sinal SIGHUP do processo pai? Eu estou tentando executar um processo em segundo plano (em um terminal shell PuTTY SSH) por nohup <command> <arg> &. Quando eu sair, clicando no Xbotão PuTTY , o processo em segundo plano será encerrado imediatamente. Quando eu sair do sistema digitando exito terminal shell PuTTY SSH, o processo continuará sendo executado em segundo plano.
userpal
3

bashpor padrão , não envia o sinal HUP para processos filho ao sair . Mais detalhadamente (obrigado @kos), ele nunca faz isso para shells que não são de login .

Você pode configurar o bash para fazer isso para shells de login, se 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.

Rmano
fonte
@kos --- sim, você está certo, mas ... então porque se eu sleep 1000 & ; exitos sleepsobrevive? Aviso que, se eu kill -HUPo sleepprocesso que vai sair. E mesmo que huponexitdefinido, o sleepsobrevive. Confuso ... (Vou tentar entender melhor e modificar o asnwer, caso contrário, vou excluí-lo).
Rmano 14/10
2

Se sleeppode sobreviver dessa maneira, se isso significa que eu posso usar esse método em vez de 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 pegar ou ignorar SIGKILL. Se você não der ao processo a chance de concluir o que está fazendo e limpar, ele poderá deixar arquivos corrompidos (ou outro estado) por aí e não poderá ser iniciado novamente. 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 está fechado. Na minha opinião, tudo, exceto o programa daemon e nohup, será morto quando o logout.

O que acontece no seu caso:

O processo pai de sleepé o bashshell atualmente em execução . Quando você faz kill -9o bash, o processo do bash não tem a chance de enviar um SIGHUPa nenhum dos processos filhos, porque SIGKILL(o que é enviado por kill -9) não pode ser capturado pelo processo. O processo de suspensão continua em execução. o sono agora se tornou um processo ó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 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 de zumbi. É o que acontece quando waitpid()não é chamado (uma responsabilidade do processo pai que não pode ser concluída quando o processo foi interrompido). O init chama waitpid()em um intervalo específico para evitar filhos zumbis.

caos
fonte
O processo está sobrevivendo, mesmo com sinais educado como TERMouHUP
heemayl
@heemayl HUP depende da configuração conchas: huponext. E TERM irá esperar até que o sono termine. No caso do comando PO sono, seria milhares de anos =)
caos
1

O &inicia o processo em segundo plano. Se você digitar ps -ef, verá que o ID do processo pai (PPID) do seu sono é a sua festa. Então saia e entre novamente. O processo permanecerá em execução após o logout. Após o login pela segunda vez, você executa ps -efnovamente. Você verá que agora o pai do seu processo de suspensão será processado com o ID "1". Isso é init, o pai de todos os processos.

ninguém
fonte
0

O uso &fará com que o programa seja executado como plano de fundo. Para ver o programa em segundo plano, use o bgcomando e para executá-lo como primeiro plano novamente, execute fg.

Sim, existem várias maneiras de manter o programa em execução até o terminal principal encerrado.

Aizuddin Zali
fonte
obrigado. a página de manual do bash é um pouco confusa. Ele disse que: "Antes de sair, um shell interativo reenvia o SIGHUP a todos os trabalhos, correndo ou parado." Mas, na verdade, a casca somente envia SIGHUP às forground empregos. os processos de fundo não têm chance de receber o sinal SIGHUP (a menos que a mudança das opções de shell 'huponexit')
tom_cat
@ kos talvez você esteja certo. Retiro a conclusão acima deste post: stackoverflow.com/questions/4298741/… agora, fico mais confuso.
tom_cat
@tom_cat Voltar para isso de novo, pensando sobre isso duas vezes: não há simplesmente nenhum caso em que a concha pode sair com um processo em primeiro plano em execução, pode ser SIGHUPped ou algo assim, mas isso não está saindo . Portanto, isso é correto, aplica-se apenas a processos em segundo plano, porque o contrário não faria sentido. No entanto a partir de novas pesquisas, mente também que huponexitfunciona apenas em shells de login, como uma concha obtido via ssh(e não, digamos, em uma concha obtido via gnome-terminal)
kos