Se eu iniciar um processo em segundo plano e depois sair, ele continuará sendo executado?

29

Ao fazer isso após uma discussão prolongada com um colega de trabalho, eu realmente gostaria de um esclarecimento aqui.

Inicio um processo em segundo plano, anexando " &" à linha de comando ou parando CTRL-Ze reiniciando em segundo plano com " bg". Então eu saio.

O que acontece?

Tínhamos certeza de que deveria ter sido morto por um SIGHUP, mas isso não aconteceu; ao fazer login novamente, o processo estava em execução feliz e pstreemostrou que foi "adotado" por init.

Este é o comportamento esperado?

Mas então, se for, qual é o nohuppropósito do comando? Parece que o processo não será morto de qualquer maneira, com ou sem ...


Editar 1

Mais alguns detalhes:

  • O comando foi iniciado a partir de uma sessão SSH, não a partir do console físico.
  • O comando foi lançado sem nohup e / ou &; foi então suspenso CTRL-Ze retomado em segundo plano com bg.
  • A sessão ssh não caiu. Houve um logout real (" exit" comando).
  • O processo foi uma scpoperação de cópia de arquivo.
  • Ao fazer login novamente, pstreemostrou o processo em execução e sendo filho de init.

Editar 2

Para declarar a questão com mais clareza: colocar um processo em segundo plano (usando &ou bg) fará com que seja ignorado SIGHUP, assim como o nohupcomando?


Editar 3

Tentei enviar manualmente um SIGHUPpara scp: ele saiu, por isso definitivamente não ignora o sinal.

Depois, tentei novamente iniciá-lo, colocando-o em segundo plano e efetuando logoff: ele foi "adotado" inite continuou sendo executado, e eu o encontrei lá ao fazer logon novamente.

Estou bastante confuso agora. Parece que não SIGHUPfoi enviado para o logoff.

Massimo
fonte
Não vi nenhuma menção à E / S do console, o que também tropeçará. Você desviou as coisas, 1>/dev/null 2>&1por exemplo, para o bash etc.?
Avery Payne
Não, não fiz. É claro que o SCP não exigia entrada padrão ... e a saída padrão não parecia ser um problema.
Massimo
A execução ou não do seu shell como um shell de login altera o desempenho, o que pode ser o caso aqui.
Warner
Feito alguns outros testes; Resumi aqui: serverfault.com/questions/117152 .
Massimo

Respostas:

20

Resposta encontrada.

Para o BASH, isso depende da huponexitopção do shell, que pode ser visualizada e / ou definida usando o shoptcomando interno.

Parece que essas opções estão desativadas por padrão, pelo menos nos sistemas baseados em RedHat.

Mais informações na página do manual BASH :

O shell sai por padrão após o recebimento de um SIGHUP. Antes de sair, um shell interativo reenvia o SIGHUP para todos os trabalhos, em execução ou interrompidos. Os trabalhos interrompidos são enviados SIGCONT para 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 renegado incorporado (consulte SHELL BUILTIN COMMANDS abaixo) ou marcado para não receber SIGHUP usando disown -h.

Se a opção de shell huponexit tiver sido definida com shopt, o bash enviará um SIGHUP para todas as tarefas quando um shell de logon interativo sair.

Massimo
fonte
2
Esse é um padrão estúpido, mas minha coragem me diz que é uma falha de RH, e não uma festança. Aliás, com o zsh você pode usar o &! como um atalho para renegar e processos bifurcados com & obter suspiro.
Jürgen Strobel
7

Concordo com a Warner e quero apenas acrescentar que você pode impedir que o shell envie SIGHUP com o comando "disown" incorporado. A página do manual bash contém uma boa descrição.

Kim
fonte
4

Você pode usar o comando nohup para iniciar o comando e redirecionar a saída para um arquivo de saída nohup. Na página do manual nohup:

nohup - run a command immune to hangups, with output to a non-tty

A outra opção é usar o comando screen . A vantagem de usar a tela é que você pode se reconectar ao processo posteriormente.

Jim
fonte
Por que os votos negativos? Usar nohup e tela são maneiras perfeitamente aceitáveis ​​de evitar a morte de um processo no logout. Existem outros, mas ambos funcionam. Qual é o problema?
24710 Jim
2
Eu acho que é um ótimo ponto, mas o Q é sobre o porquê de seus processos não serem mortos, NÃO "como impedir que eles sejam mortos".
CarpeNoctem
2

Quando você coloca um processo em segundo plano, ele ainda será o processo filho do shell que o está executando.

Todos os processos filhos em execução sob um shell recebem um SIGHUP na saída. O desempenho varia um pouco, dependendo da situação exata, detalhada detalhadamente na página de manual do bash. Outras conchas provavelmente têm descrições semelhantes.

O Apache e outros daemons geralmente recarregam a configuração no SIGHUP. Os utilitários de espaço do usuário geralmente morrem. O desempenho do aplicativo vinculado aos sinais pode ser exclusivo do aplicativo.

Warner
fonte
Então o processo deveria ter recebido um SIGHUP nesse caso, certo? Talvez apenas tenha ignorado, eu vou verificar.
Massimo
Sim, exatamente. É isso que acredito ser a situação. Se você realmente duvida do desempenho documentado, pode criar um pequeno script para capturar o sinal e registrá-lo.
Warner
0

Qual foi o processo? O desempenho descrito na postagem anterior 1 foi preciso.

Certas funções e processos de script podem capturar sinais. enquanto loops podem fugir como loucos.

Vejo:

Sessão SSH cai - O comando continua em execução?

Editar 1 às 16:22

Na página de manual do bash:

The shell exits by default upon receipt of a SIGHUP.   Before  exiting,
an  interactive  shell  resends  the  SIGHUP  to  all  jobs, running or
topped.

A pesquisa inicial 1 está mostrando que o OpenSSH provavelmente ignora o SIGHUP, talvez mais sinais.

Warner
fonte
Na verdade, esse post me inspirou a fazer a pergunta. Para detalhes, consulte a edição acima.
Massimo
2
As respostas em outro segmento faz parecer que você precisa ler-se no comando SCP você está usando e ver como ele responde a SIGHUP
mfinni
E 'nohup' é para comandos que você sabe que morrerão com um SIGHUP e você não quer que eles o façam, eu acho.
mfinni
A página de manual simplesmente não conta; Vou tentar matá-lo -HUP amanhã ...
Massimo
-1

Se você não iniciou o comando por meio de uma ferramenta como screen, então, quando a sessão terminar, todos os trabalhos / tarefas associados a essa sessão serão executados.

Warren
fonte
Era exatamente o que eu estava pensando, exceto ... eles simplesmente não pensavam.
Massimo
eles têm toda vez que eu faço o que você descreveu ... talvez dependa do shell que você usa?
warren
-1 Eles não; a resposta não é tão simples. Acabei de testar um shell script simples que iniciei em segundo plano; fez um loop e enviou a saída para um arquivo temporário. Ele continuou funcionando depois que eu saí do terminal (como visto tail -fno arquivo temporário. Isso em uma máquina CentOS 7.1 usando bash.
Mike S
@MikeS - por favor demonstre. Eu nunca ter testemunhado o comportamento que você descreve
Warren
@warren - Veja minha resposta em serverfault.com/questions/117152/… . Observe que várias pessoas alegam um comportamento diferente do que você descreve; de fato, Massimo postou precisamente porque seu processo continuou.
Mike S