shell - with - ssh remote execution
Como usar o SSH para executar um script de shell em uma máquina remota? (9)
A resposta aqui ( https://stackoverflow.com/a/2732991/4752883 ) funciona muito bem se você está tentando executar um script em uma máquina Linux remota usando plink
ou ssh
. Ele funcionará se o script tiver várias linhas no linux
.
** No entanto, se você estiver tentando executar um script em lote localizado em uma máquina linux/windows
local e sua máquina remota for Windows
, ela consistirá de várias linhas usando **
plink [email protected] -m local_script.bat
não vai funcionar.
Apenas a primeira linha do script será executada. Esta é provavelmente uma limitação do plink
.
Solução 1:
Para executar um script em lotes de várias linhas (especialmente se for relativamente simples, consistindo em algumas linhas):
Se o seu script em lote original é o seguinte
cd C:\Users\ipython_user\Desktop
python filename.py
você pode combinar as linhas juntas usando o separador "&&" da seguinte maneira no seu arquivo local_script.bat
: https://stackoverflow.com/a/8055390/4752883 :
cd C:\Users\ipython_user\Desktop && python filename.py
Após essa mudança, você pode executar o script como indicado aqui por @ JasonR.Coombs: https://stackoverflow.com/a/2732991/4752883 com:
`plink [email protected] -m local_script.bat`
Solução 2:
Se o seu script em lote for relativamente complicado, talvez seja melhor usar um script em lote que encapsule o comando plink, assim como o indicado aqui por @Martin https://stackoverflow.com/a/32196999/4752883 :
rem Open tunnel in the background
start plink.exe -ssh [username]@[hostname] -L 3307:127.0.0.1:3306 -i "[SSH
key]" -N
rem Wait a second to let Plink establish the tunnel
timeout /t 1
rem Run the task using the tunnel
"C:\Program Files\R\R-3.2.1\bin\x64\R.exe" CMD BATCH qidash.R
rem Kill the tunnel
taskkill /im plink.exe
Eu tenho que executar um script de shell (windows / Linux) em uma máquina remota.
Eu tenho SSH configurado na máquina A e B. Meu script está na máquina A, que irá executar alguns dos meus códigos em uma máquina remota, máquina B.
Os computadores locais e remotos podem ser Windows ou sistema baseado em Unix.
Existe uma maneira de executar isso usando plink / ssh?
Além disso, não se esqueça de fugir de variáveis se quiser buscá-las no host de destino.
Isso me pegou no passado.
Por exemplo:
[email protected]> ssh [email protected] "echo \$HOME"
imprime / home / user2
enquanto
[email protected]> ssh [email protected] "echo $HOME"
imprime / home / user
Outro exemplo:
[email protected]> ssh [email protected] "echo hello world | awk '{print \$1}'"
imprime "olá" corretamente.
Esta é uma pergunta antiga, e a resposta de Jason funciona bem, mas eu gostaria de acrescentar isto:
ssh [email protected] <<'ENDSSH'
#commands to run on remote host
ENDSSH
Isso também pode ser usado com su e comandos que requerem entrada do usuário. (observe o '
escape heredoc)
Edit: Uma vez que esta resposta continua recebendo bits de tráfego, gostaria de acrescentar ainda mais informações para este maravilhoso uso de heredoc:
Você pode aninhar comandos com essa sintaxe e essa é a única maneira de o aninhamento funcionar (de maneira sã)
ssh [email protected] <<'ENDSSH'
#commands to run on remote host
ssh [email protected] <<'END2'
# Another bunch of commands on another host
wall <<'ENDWALL'
Error: Out of cheese
ENDWALL
ftp ftp.secureftp-test.com <<'ENDFTP'
test
test
ls
ENDFTP
END2
ENDSSH
Você pode realmente ter uma conversa com alguns serviços como telnet, ftp, etc. Mas lembre-se que heredoc apenas envia o stdin como texto, ele não espera por resposta entre linhas
Edit: Acabei de descobrir que você pode recuar o interior se você usar <<-END
!
ssh [email protected] <<-'ENDSSH'
#commands to run on remote host
ssh [email protected] <<-'END2'
# Another bunch of commands on another host
wall <<-'ENDWALL'
Error: Out of cheese
ENDWALL
ftp ftp.secureftp-test.com <<-'ENDFTP'
test
test
ls
ENDFTP
END2
ENDSSH
(Eu acho que isso deve funcionar)
Veja também http://tldp.org/LDP/abs/html/here-docs.html
Este script bash faz o ssh em uma máquina remota de destino, e executa algum comando na máquina remota, não esqueça de instalar o expect antes de executá-lo (no mac brew install expect
)
#!/usr/bin/expect
set username "enterusenamehere"
set password "enterpasswordhere"
set hosts "enteripaddressofhosthere"
spawn ssh [email protected]$hosts
expect "[email protected]$hosts's password:"
send -- "$password\n"
expect "$"
send -- "somecommand on target remote machine here\n"
sleep 5
expect "$"
send -- "exit\n"
Eu uso este para executar um script de shell em uma máquina remota (testado em / bin / bash):
ssh [email protected] . /home/deploy/path/to/script.sh
Primeiro, copie o script para a Máquina B usando scp
[user @ machineA] $ scp / caminho / para / usuário do script @ machineB: / home / user / path
Então, basta executar o script
[usuário @ máquinaA] $ ssh usuário @ machineB "/ home / user / path / script"
Isso funcionará se você tiver dado permissão executável ao script.
Se você quer executar o comando como este, o comando temp=`ls -a` echo $temp
`causará erros.
abaixo comando irá resolver este problema ssh [email protected] ''' temp=`ls -a` echo $temp '''
Supondo que você queira fazer isso automaticamente de uma máquina "local", sem fazer login manualmente na máquina "remota", você deve procurar uma extensão TCL conhecida como Expect, ela é projetada precisamente para esse tipo de situação. A home page abaixo parece meio ruim, mas não deixe que isso o dissuadisse; Eu também forneci um link para um script para login / interação via SSH.
<hostA_shell_prompt>$ ssh [email protected] "ls -la"
Isso solicitará a senha, a menos que você tenha copiado a chave pública do usuário hostA para o arquivo authorized_keys na home do diretório do usuário .ssh. Isso permitirá a autenticação sem senha (se aceita como um método auth na configuração do servidor ssh)