Obter ssh para transmitir sinais

21

Eu quero poder enviar sinais (o SIGINT é o mais importante) através do ssh.

Este comando:

ssh server "sleep 1000;echo f" > foo

irá iniciar a suspensão no servidor e após 1000 segundos colocará 'f \ n' no arquivo foo na minha máquina local. Se eu pressionar CTRL-C (ou seja, enviar SIGINT para ssh), ele irá 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 é um terminal, recebo este erro:

Pseudo-terminal will not be allocated because stdin is not a terminal.

e depois o SIGINT ainda não foi encaminhado.

Então eu tentei:

ssh server -t -t "sleep 1000;echo f" > output

Mas a saída em foo não é 'f \ n', mas sim 'f \ r \ n' que é desastrosa na minha situação (já que minha saída é de dados binários).

Acima eu uso "sleep 1000; echo f", mas na realidade isso é fornecido pelo usuário, assim ele pode conter qualquer coisa. No entanto, se conseguirmos fazer com que funcione para "dormir 1000; eco f", podemos muito bem fazê-lo funcionar para todas as situações realistas.

Eu realmente não me importo em obter um pseudo-terminal no outro lado, mas não consegui encontrar outra maneira de fazer o ssh encaminhar meu SIGINT.

Existe outro jeito?

Editar:

O usuário pode dar comandos que leiam dados binários de stdin, como:

seq 1000 | gzip | ssh server "zcat|bzip2; sleep 1000" | bzcat > foo

O usuário pode fornecer comandos que são intensivos em CPU, como:

ssh server "timeout 1000 burnP6"

Editar2:

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 apontar na direção certa.

    
por Ole Tange 04.06.2012 / 23:02

5 respostas

10

Resposta curta:

ssh -t fs "stty isig intr ^N -echoctl ; trap '/bin/true' SIGINT; sleep 1000; echo f" > foo

e pare o programa por CTRL + N.

Longa explicação:

  1. Você deve usar stty option intr para alterar seu servidor ou o caractere de interrupção local para não colidir uns com os outros. No comando acima, mudei o caractere de interrupção do servidor para CTRL + N. Você pode alterar seu caractere de interrupção local e deixar o do servidor sem nenhuma alteração.
  2. Se você não quiser que o caractere de interrupção esteja em sua saída (e qualquer outro caractere de controle), use stty -echoctl .
  3. Você deve assegurar que os caracteres de controle estão ativados no bash do servidor invocado pelo sshd. Se não, você pode acabar com processos ainda por aí depois de sair. %código%
  4. Você realmente captura stty isig signal por SIGINT com a instrução vazia. Sem a armadilha, você não terá nenhuma stdout após o sinal SIGINT.
por 05.06.2012 / 13:10
3

Eu tentei todas as soluções e esta foi a melhor:

ssh host "sleep 99 < <(cat; kill -INT 0)" <&1

link

    
por 16.04.2015 / 19:04
2

Acho que você poderia encontrar o PID do processo que está executando no servidor e enviar um sinal usando outro comando ssh (assim: ssh 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 SIGUSR1 e lêem um arquivo de configuração). No meu caso, encontrar o PID é fácil, porque eu tenho nomes de processos exclusivos e posso encontrar o PID enviando uma solicitação ps via ssh .

    
por 05.06.2012 / 11:06
1

A solução evoluiu para o link

$SIG{CHLD} = sub { $done = 1; };
$pid = fork;
unless($pid) {
    # Make own process group to be able to kill HUP it later
    setpgrp;
    exec $ENV{SHELL}, "-c", ($bashfunc."@ARGV");
    die "exec: $!\n";
}
do {
    # Parent is not init (ppid=1), so sshd is alive
    # Exponential sleep up to 1 sec
    $s = $s < 1 ? 0.001 + $s * 1.03 : $s;
    select(undef, undef, undef, $s);
} until ($done || getppid == 1);
# Kill HUP the process group if job not done
kill(SIGHUP, -${pid}) unless $done;
wait;
exit ($?&127 ? 128+($?&127) : 1+$?>>8)
    
por 03.08.2015 / 17:00
0

----- command.sh

#! /bin/sh
trap 'trap - EXIT; kill 0; exit' EXIT
(sleep 1000;echo f) &
read ans

----- no terminal local

sleep 864000 | ssh -T server command.sh > foo
    
por 14.04.2015 / 22:14