Quero poder enviar sinais (SIGINT é o mais importante) através do ssh.
Este comando:
ssh server "sleep 1000;echo f" > foo
iniciará o modo de suspensão no servidor e após 1000 segundos ele colocará 'f \ n' no arquivo foo na minha máquina local. Se eu pressionar CTRL-C (por exemplo, enviar SIGINT para ssh), ele matará o ssh, mas não matará o sono no servidor remoto. Eu quero matar o sono no servidor remoto.
Então eu tentei:
ssh server -t "sleep 1000;echo f" > foo
Mas se stdin não for um terminal, recebo este erro:
Pseudo-terminal will not be allocated because stdin is not a terminal.
e o SIGINT ainda não é encaminhado.
Então eu tentei:
ssh server -t -t "sleep 1000;echo f" > output
Mas então a saída em foo não é 'f \ n', mas sim 'f \ r \ n', o que é desastroso na minha situação (como minha saída são dados binários).
No exemplo acima, uso "sleep 1000; echo f", mas, na realidade, é fornecido pelo usuário, portanto pode conter qualquer coisa. No entanto, se podemos fazê-lo funcionar para "dormir 1000; eco de", provavelmente podemos fazê-lo para todas as situações realistas.
Realmente não me importo em obter um pseudo-terminal na outra extremidade, mas não consegui encontrar outra maneira de obter o ssh para encaminhar meu SIGINT.
Existe outro caminho?
Editar:
O usuário pode fornecer comandos que leem dados binários do stdin, como:
seq 1000 | gzip | ssh server "zcat|bzip2; sleep 1000" | bzcat > foo
O usuário pode fornecer comandos que consomem muita CPU, como:
ssh server "timeout 1000 burnP6"
Edit2:
A versão que parece funcionar para mim é:
your_preprocessing |
uuencode a | ssh -tt -oLogLevel=quiet server "stty isig -echoctl -echo ; uudecode -o - |
your_command |
uuencode a" | uudecode -o - |
your_postprocessing
Obrigado ao digital_infinity por me indicar a direção certa.
ssh
deve ser mais complicado do que o que você mostra como exemplos, porque você pode obter o comportamento desejado com um simples rearranjo:sleep 1000 && ssh server "echo f" > foo
(Tem que ser&&
, não;
, para que matarsleep
impeça assh
execução do comando). Estou certo, torne seus exemplos mais representativos do seu uso real, para que uma resposta melhor possa ser dada.Respostas:
Resposta curta:
e pare o programa com CTRL + N.
Explicação longa:
stty
opçãointr
para alterar o servidor ou o caractere de interrupção local para não colidir. No comando acima, alterei o caractere de interrupção do servidor para CTRL + N. Você pode alterar o caractere de interrupção local e deixar o do servidor sem nenhuma alteração.stty -echoctl
.stty isig
SIGINT
sinaltrap '/bin/true' SIGINT
com a declaração vazia. Sem a armadilha, você não terá nenhum desvio padrão após o sinal SIGINT do seu lado.fonte
seq 1000 | gzip | ssh -tt dell-test "zcat|bzip2" | bzcat > foo
também não funciona. Para que este comando funcione, precisamos removê-lo-tt
. Assim, a alocação de pseudo terminal provavelmente leva alguma entrada de stdin(sleep 1; seq 1000 ) | gzip | uuencode bin | ssh -tt dell-test "stty isig intr ^N -echoctl -echo ; trap '/bin/true' SIGINT; sleep 1; uudecode -o /dev/stdout | zcat |bzip2 | uuencode bin2 " | uudecode -o /dev/stdout | bzcat >foo
. Embora o caractere de interrupção não funcione - precisamos de algum método de transmissão para o caractere de interrupção enquanto stdin estiver ocupado .Eu tentei todas as soluções e esta foi a melhor:
/programming/3235180/starting-a-process-over-ssh-using-bash-and-then-killing-it-on-sigint/25882610#25882610
fonte
sleep
processo caso a conexão seja perdida.sleep
, não deveria? Eu adicionei algunsdate >> /tmp/killed
após ocat
, mas não foi acionado. Existe algum tempo limite envolvido? Estou usando o Zsh normalmente, mas também o testei com o bash como o shell de login remoto.-o ServerAliveInterval=3 -o ServerAliveCountMax=2
permite detectá-lo rapidamente, mas há algo para o lado do servidor?Eu acho que você pode encontrar o PID do processo em execução no servidor e enviar um sinal usando outro
ssh
comando (como estessh server "kill -2 PID"
:).Eu uso esse método para enviar sinais de reconfiguração para aplicativos em execução em uma máquina diferente (meus aplicativos capturam o SIGUSR1 e leem um arquivo de configuração). No meu caso, é fácil encontrar o PID, pois tenho nomes de processo exclusivos e posso encontrá-lo enviando uma
ps
solicitação viassh
.fonte
A solução evoluiu para http://www.gnu.org/software/parallel/parallel_design.html#Remote-Ctrl-C-and-standard-error-stderr
fonte
----- command.sh
----- no terminal local
fonte