Chegando ssh para executar um comando em background no computador de destino
Pergunta
Este é um pergunta para o Como fazer você usar o ssh em um script de shell? questão.Se eu quiser executar um comando na máquina remota, que roda em background no computador, como faço para obter o comando ssh para voltar?Quando eu tento incluir apenas o " e " comercial (&) no final do comando, ele simplesmente trava.A forma exata do comando parecido com este:
ssh user@target "cd /some/directory; program-to-execute &"
Qualquer idéias?Uma coisa a notar é que os inícios de sessão para a máquina de destino sempre produzir um texto do banner e eu tenho SSH as chaves definidas até então, nenhuma senha é necessária.
Solução
Eu tive esse problema em um programa que eu escrevi há um ano -- acontece que a resposta é bastante complicada.Você vai precisar usar nohup bem como redirecionamento de saída, como explicado no artigo da wikipédia sobre nohup, copiado aqui para sua conveniência.
Nohuping backgrounded postos de trabalho é para exemplo útil quando conectado via SSH, desde backgrounded trabalhos podem causar o shell para travar a saída devido a uma corrida condição [2].Esse problema também pode ser superados redirecionando todos os três Fluxos de e/S:
nohup myprogram > foo.out 2> foo.err < /dev/null &
Outras dicas
Esta tem sido a maneira mais para fazer isso para mim:-
ssh -n -f user@host "sh -c 'cd /whereever; nohup ./whatever > /dev/null 2>&1 &'"
A única coisa execução após esse é o real comando na máquina remota
Redirecionar fd do
Saída precisa ser redirecionado com &>/dev/null
que redireciona tanto stderr e stdout para /dev/null e é sinônimo de >/dev/null 2>/dev/null
ou >/dev/null 2>&1
.
Parantheses
A melhor maneira é usar sh -c '( ( command ) & )'
onde comando é nada.
ssh askapache 'sh -c "( ( nohup chown -R ask:ask /www/askapache.com &>/dev/null ) & )"'
Nohup Shell
Você também pode usar nohup directamente para iniciar o shell:
ssh askapache 'nohup sh -c "( ( chown -R ask:ask /www/askapache.com &>/dev/null ) & )"'
Bom Lançamento
Outro truque é usar agradável para iniciar o comando/shell:
ssh askapache 'nice -n 19 sh -c "( ( nohup chown -R ask:ask /www/askapache.com &>/dev/null ) & )"'
Eu só queria mostrar um exemplo funcional que você pode recortar e colar:
ssh REMOTE "sh -c \"(nohup sleep 30; touch nohup-exit) > /dev/null &\""
Se você não/não pode manter a conexão aberta, você pode usar tela, se você tem os direitos para instalá-lo.
user@localhost $ screen -t remote-command
user@localhost $ ssh user@target # now inside of a screen session
user@remotehost $ cd /some/directory; program-to-execute &
Para desligar o ecrã de sessão: ctrl-a d
A tela de lista de sessões:
screen -ls
Para recolocar uma sessão:
screen -d -r remote-command
Note que a tela também pode criar várias conchas dentro de cada sessão.Um efeito semelhante pode ser alcançado com o tmux.
user@localhost $ tmux
user@localhost $ ssh user@target # now inside of a tmux session
user@remotehost $ cd /some/directory; program-to-execute &
Para desconectar a sessão do tmux: ctrl-b d
A tela de lista de sessões:
tmux list-sessions
Para recolocar uma sessão:
tmux attach <session number>
O padrão do tmux tecla control 'ctrl-b"é um pouco difícil de usar, mas existem vários exemplos de tmux configs que acompanham o tmux que você pode tentar.
Forma mais fácil e rápida é usar o 'no' comando:
ssh usuário@alvo "agora -f /home/foo.sh"
Eu acho que você vai ter que combinar um par dessas respostas para conseguir o que deseja.Se você usar o nohup em conjunto com o ponto-e-vírgula, e enrole a coisa toda em aspas, em seguida, você obtém:
ssh user@target "cd /some/directory; nohup myprogram > foo.out 2> foo.err < /dev/null"
o que parece funcionar para mim.Com nohup, você não precisa acrescentar o & para o comando a ser executado.Também, se você não precisa ler a saída do comando, você pode usar
ssh user@target "cd /some/directory; nohup myprogram > /dev/null 2>&1"
para redireccionar a saída para /dev/null.
Isso funcionou para mim pode tempos:
ssh -x remoteServer "cd yourRemoteDir; ./yourRemoteScript.sh </dev/null >/dev/null 2>&1 & "
Na verdade, sempre que eu precisar executar um comando em um computador remoto que é complicado, eu gostaria de colocar o comando em um script na máquina de destino, e basta executar o script usando o comando ssh.
Por exemplo:
# simple_script.sh (located on remote server)
#!/bin/bash
cat /var/log/messages | grep <some value> | awk -F " " '{print $8}'
E, em seguida, basta executar o seguinte comando no computador de origem:
ssh user@ip "/path/to/simple_script.sh"
Eu estava tentando fazer a mesma coisa, mas com a complexidade adicional que eu estava tentando fazê-lo a partir do Java.Assim, em uma máquina com java, eu estava tentando executar um script em outra máquina, no plano de fundo (com nohup).
A partir da linha de comando, aqui é que funcionou:(você pode não precisar de "-eu keyFile" se você não a necessita de ssh para o host)
ssh -i keyFile user@host bash -c "\"nohup ./script arg1 arg2 > output.txt 2>&1 &\""
Note que a minha linha de comandos, existe um argumento após o "-c", que é tudo entre aspas.Mas para que ele funcione no outro extremo, ele ainda precisa de aspas, então eu tive que colocar escapou aspas dentro dele.
A partir do java, aqui está o que funcionou:
ProcessBuilder b = new ProcessBuilder("ssh", "-i", "keyFile", "bash", "-c",
"\"nohup ./script arg1 arg2 > output.txt 2>&1 &\"");
Process process = b.start();
// then read from process.getInputStream() and close it.
Levou um pouco de tentativa & erro para obter esse trabalho, mas ele parece funcionar bem agora.
Você pode fazer como esta...
sudo /home/script.sh -opt1 > /tmp/script.out &
Ele apareceu muito conveniente para mim ter um remoto sessão do tmux utilizando o tmux new -d <shell cmd>
sintaxe:
ssh someone@elsewhere 'tmux new -d sleep 600'
Isto irá iniciar nova sessão no elsewhere
de acolhimento e de comando ssh na máquina local irá retornar ao shell quase que instantaneamente.Em seguida, você pode ssh para o host remoto e tmux attach
para que a sessão.Observe que não há nada sobre o local do tmux execução, somente controle remoto!
Além disso, se você deseja que sua sessão de persistir depois que o trabalho é feito, simplesmente adicione uma concha lançador após o seu comando, mas não se esqueça de colocar entre aspas:
ssh someone@elsewhere 'tmux new -d "~/myscript.sh; bash"'
Eu acho que isso é o que você precisa:Em primeiro lugar você precisa para instalar sshpass
na sua máquina.em seguida, você pode escrever seu próprio script:
while read pass port user ip; do
sshpass -p$pass ssh -p $port $user@$ip <<ENDSSH1
COMMAND 1
.
.
.
COMMAND n
ENDSSH1
done <<____HERE
PASS PORT USER IP
. . . .
. . . .
. . . .
PASS PORT USER IP
____HERE
Primeiro, siga este procedimento:
Logon como Um usuário e gerar um par de chaves de autenticação.Não digite uma senha:
a@A:~> ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/a/.ssh/id_rsa):
Created directory '/home/a/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/a/.ssh/id_rsa.
Your public key has been saved in /home/a/.ssh/id_rsa.pub.
The key fingerprint is:
3e:4f:05:79:3a:9f:96:7c:3b:ad:e9:58:37:bc:37:e4 a@A
Agora utilize o ssh para criar um diretório ~/.o ssh como usuário b em B.(O diretório que já pode existir, o que é bom):
a@A:~> ssh b@B mkdir -p .ssh
b@B's password:
Finalmente acrescentar uma nova chave pública para b@B:.ssh/authorized_keys e insira b a senha pela última vez:
a@A:~> cat .ssh/id_rsa.pub | ssh b@B 'cat >> .ssh/authorized_keys'
b@B's password:
A partir de agora você pode entrar em B, como b a partir de Uma como de um sem palavra-passe:
a@A:~> ssh b@B
então isso vai funcionar sem introduzir uma palavra-passe
ssh b@B "cd /alguns/diretório;programa-para-executar &"