Por que o SSH -t não espera por processos em segundo plano?

13

Por que ssh -tnão espera pela conclusão dos trabalhos em segundo plano?

Exemplo:

ssh user@example 'sleep 2 &'

Isso funciona como esperado, pois o ssh retorna após 2 segundos, enquanto

ssh user@example -t 'sleep 2 &'

não espera sleepterminar e retorna imediatamente.

Alguém pode explicar a razão por trás disso? Existe uma maneira de deixarssh -t aguardar a conclusão de todos os processos em segundo plano antes de retornar?

Meu caso de uso é com o qual inicio um script ssh -t, e esse script inicia vários trabalhos em segundo plano que devem permanecer ativos após a conclusão do script principal. Com ssh -tisso não é possível até agora.

Philipp Murry
fonte

Respostas:

22

Sem -t, sshdobtém o stdout do shell remoto (e os filhos gostam sleep) e o stderr através de dois canais (e também envia a entrada do cliente através de outro canal).

sshd aguarda o processo no qual iniciou o shell de logon do usuário, mas também, após o término do processo, aguarda porof no canal stdout (não no tubo stderr no caso do openssh, pelo menos).

Eof acontece quando não há descritor de arquivo por nenhum processo aberto na extremidade de gravação do canal, o que normalmente acontece apenas quando todos os processos que não tiveram seu stdout redirecionado para outra coisa se foram.

Quando você usa -t, sshdnão usa canos. Em vez disso, toda a interação (stdin, stdout, stderr) com o shell remoto e seus filhos é feita usando um par pseudo-terminal.

Com um par pseudo-terminal, para sshdinteragir com o lado mestre, não há manipulação de Eof semelhante ou alguma maneira de saber se ainda existem processos com fds abertos no lado escravo do pseudo-terminal, portanto, apenas aguarde o término de o processo no qual ele executou o shell de login do usuário remoto e, em seguida, sai.

Após essa saída, o lado mestre do par pty é fechado, o que significa que o pty é destruído; portanto, os processos controlados pelo escravo receberão um SIGHUP (que por padrão os encerraria).

Stéphane Chazelas
fonte
1
obrigado pela resposta completa! Outra coisa que eu gostaria de saber: todos os processos em segundo plano terminam quando o pseudo terminal sai? o script que estou iniciando inicia um serviço, que funciona bem com o ssh. mas ao usar ssh -t, o serviço não é iniciado. parece que o serviço é encerrado quando o ssh retorna.
Philipp Murry
Na verdade, existe uma maneira de o lado mestre de um pseudo-terminal saber quando todos os descritores de arquivos escravos foram fechados. É o mesmo mecanismo acionado por um terminal real quando todos os descritores de arquivo foram fechados, na verdade.
JdeBP
@JdeBP, você gostaria de expandir? Não sei bem o que você quer dizer. Emuladores AFAICT terminais (xterm e gnome-terminal de, pelo menos,) não se preocupam com processos ainda ter fds abertas para o escravo, quando o processo que executou o escudo em fieiras
Stéphane Chazelas
@PhilippMurry Você pode usar nohuppara manter um script em execução assim. (Você também pode considerar iniciar de longa execução empregos dentro de tmuxmodo que você pode monitorar seu progresso de forma interativa, mas um arquivo de log funciona bem.)
jpaugh
5

Use wait:

ssh user@example -t 'sleep 2 & wait'
Ipor Sircer
fonte