Comando remoto PuTTY contendo loop while

Comando remoto PuTTY contendo loop while

Estou tentando automatizar várias tarefas comuns que faço por SSH em um servidor remoto. Para isso, estou utilizando o PuTTY e sua opção de "comando remoto" (Conexão > SSH) em diversas sessões salvas. Meu comando remoto é mais ou menos assim:

~/scripts/test; $SHELL -l

O script executado difere por sessão salva e executa tarefas diferentes. $SHELL -lmantém a sessão PuTTY ativa após o término da execução do script.

Tudo isso está funcionando perfeitamente para a maioria dos scripts que estou executando. No entanto, tenho um que usa um loop while para executar uma série de comandos até terminar com Ctrl+C. O script inicia bem, mas o shell PuTTY não permanece ativo depois de encerrado. $SHELL -lnão parece estar sendo executado.

Um exemplo de script com esse comportamento é o seguinte:

while true; do
echo "."
sleep 2
done

O seguinte funciona bem executado manualmente, vejo a saída esperada do segundo comando:

~/scripts/test; echo "done"

No entanto, o segundo comando do "comando remoto" do PuTTY não é executado. Na verdade, se eu alterar o comando remoto para incluir um echo, ele não será exibido.

~/scripts/test; echo "done"; $SHELL -l

Então, acho que minha pergunta é: por que o segundo comando da lista não é executado pelo comando remoto, enquanto é executado manualmente? E, mais importante, o que posso fazer a respeito?

Se for relevante, estou executando o PuTTY no Ubuntu 14.04.

Responder1

Quando você executa puttyou ssh- não acho que haja alguma diferença neste contexto - com um comando para executar no sistema remoto, o servidor ssh remoto executa o comando como um comando shell:

/bin/bash -c '~/scripts/test; $SHELL -l'

Então você tem uma bashinstância no sistema remoto executando esse pipeline. Você também tem outra bashinstância, iniciada pela primeira instância, executando este script de “teste”.

Quando você digita Control-C, puttyenvia o caractere para o sistema remoto, onde é interpretado pelo seu TTY como o caractere de interrupção. Isso resulta no envio de um SIGINT (sinal de interrupção) para processos que estão anexados ao TTY. Isso interrompe ambos os processos do shell, fazendo com que ambos sejam encerrados. Você deseja que a instância do shell pai ignore o SIGINT.

O comando bash para ignorar o SIGINT é:

trap "" INT

Portanto, para desabilitar o SIGINT para seu pipeline, você alteraria seu comando original para:

trap '' INT; ~/scripts/test; $SHELL -l

Mas isso também desativa o SIGINT para processos filhos, o que tornaria o script de "teste" imune a Ctrl-C. Portanto, você precisa reativar o SIGINT para o script de teste. O comando para isso é:

trap INT

Você pode adicionar essa linha ao próprio script de teste ou ao pipeline:

trap '' INT; ( trap INT; ~/scripts/test ); $SHELL -l

Agora, ao pressionar Ctrl-C, você deve interromper o processo de "teste", mas não o processo pai que está executando o pipeline de comando.

Você pode testar isso sem usar putty ou ssh. Basta executar estes comandos e tentar pressionar Ctrl-C enquanto o “sleep” está em execução:

bash -c 'sleep 15; echo foo'                  # Ctrl-C kills sleep; doesn't print "foo"
bash -c 'trap "" INT ; sleep 15; echo foo'    # Ctrl-C has no effect
bash -c 'trap "" INT; ( trap INT; sleep 15 ); echo foo'    # Kills sleep, prints "foo"

Responder2

ctrl+c para o comando remoto putty está na verdade interrompendo a sessão ssh, portanto, deve-se esperar que ele não execute os comandos remotos restantes. Se o seu objetivo é apenas manter a sessão ativa, apenas o seu loop infinito deve ser suficiente.

informação relacionada