Usando SSH para iniciar remotamente um processo

18

Eu escrevi um script que estou usando para enviar e implantar um novo serviço em várias máquinas sob meu controle e, para executar o processo, estou usando o ssh para iniciar remotamente o processo. Infelizmente, sempre que eu uso o SSH para iniciar o processo, o comando SSH parece nunca retornar, causando a interrupção do script.

O comando é especificado como: ssh $ user @ $ host "/ root / command &". Sempre que executo comandos simples, como ps ou who, o comando SSH retorna imediatamente, no entanto, quando tento iniciar meu processo, ele não retorna. Eu tentei truques como agrupar meu processo em um script bash simples que inicia o processo e sai, no entanto, isso também trava o comando SSH (mesmo que o script bash faça eco de uma mensagem de sucesso e saia normalmente).

Alguém tem alguma idéia do que está causando esse comportamento e como posso obter o comando SSH para retornar assim que o processo foi iniciado?

Obrigado por suas idéias!

rmrobins
fonte
Postar na linha de comando exato que você está usando ... omitir senhas / usernames / IPs
Joseph Kern
ssh $ SSH_USER @ $ HOST_ADDR "/ root / AppName &"
rmrobins
Devo mencionar que configurei chaves SSH, portanto, não é necessário usar senhas para executar comandos nos sistemas remotos.
Rmrobins 06/07/2009
@rmrobins, um passo muito bom - definindo autenticação de chave pública.
Nik

Respostas:

28

O SSH conecta stdin, stdout e stderr do shell remoto ao seu terminal local, para que você possa interagir com o comando que está sendo executado no lado remoto.

Como efeito colateral, ele continuará sendo executado até que essas conexões sejam fechadas, o que ocorre apenas quando o comando remoto e todos os seus filhos (!) Foram finalizados (porque os filhos, que é o que "&" inicia, herdam std * de seus processo pai e mantenha-o aberto).

Então você precisa usar algo como

ssh user@host "/script/to/run < /dev/null > /tmp/mylogfile 2>&1 &"

Os <,> e 2> & 1 redirecionam stdin / stdout / stderr para longe do seu terminal. O "&" faz com que seu script vá para segundo plano. Na produção, é claro que você redirecionaria stdin / err para um arquivo de log adequado.

Vejo

http://osdir.com/ml/network.openssh.general/2006-05/msg00017.html

Editar:

Acabei de descobrir que o < /dev/nullacima não é necessário (mas redirecionar stdout / err é ). Não faço ideia porque ...

sleske
fonte
Obrigado, é exatamente isso que eu estava procurando - não me ocorreu que o processo herdaria o std * mesmo ao usar & para iniciá-lo em segundo plano.
Rmrobins 06/07/2009
+1! Funciona para mim. E você também pode imprimir a saída ecoando o arquivo de log: ssh user@host "/script/to/run > /tmp/ssh.stdout 2>&1 && cat /tmp/ssh.stdout && rm -f /tmp/ssh.stdout"
Fishdrowned
5

Você pode tentar nohup . Homem nohup para mais detalhes.

ssh host "nohup script &"

Se você deseja manter a saída na máquina remota, aqui está uma variante .

ssh user@host 'export REMOTE=myname; nice nohup ./my-restart >
logfile.log 2>&1 &'
Jauder Ho
fonte
5

Outra alternativa seria iniciar um desanexado screen(1), algo como:

ssh -l user host "screen -d -m mycommand"

Isso iniciará uma tela desanexada (que captura toda a interação dentro dela) e retornará imediatamente, encerrando a sessão ssh.

Com um pouco mais de habilidade, você pode resolver chamadas de comandos remotos bastante complexas dessa maneira.

towo
fonte
4
 -f      Requests ssh to go to background just before command execution.
         This is useful if ssh is going to ask for passwords or
         passphrases, but the user wants it in the background.  This
         implies -n.  The recommended way to start X11 programs at a
         remote site is with something like ssh -f host xterm.

         If the ExitOnForwardFailure configuration option is set to “yes”,
         then a client started with -f will wait for all remote port for‐
         wards to be successfully established before placing itself in the
         background.
Urso de pelúcia
fonte
11
O problema com esse método é que o comando SSH não é realmente encerrado, ele está simplesmente oculto em segundo plano, portanto, o host que executa o script terá um grande número de comandos SSH em segundo plano que nunca retornam porque os comandos SSH nunca retornam ( ou seja, a raiz do problema que deseja resolver)
rmrobins
-1

Eu acho que a maneira correta seria

ssh user@host exec script.sh &
nik
fonte
Não, isso não funciona para mim. Por que deveria?
sleske
Eu não usei o background push over ssh, estava tentando sem um termo em mãos. foi mal.
Nik