¿Cómo utilizar SSH para ejecutar un script de shell local en una máquina remota?
Tengo que ejecutar un script de shell local (Windows/Linux) en una máquina remota.
Tengo SSH configurado tanto en la máquina A como en la B. Mi script está en la máquina A, que ejecutará parte de mi código en una máquina remota, la máquina B.
Las computadoras locales y remotas pueden ser sistemas basados en Windows o Unix.
¿Hay alguna manera de ejecutar esto usando plink/ssh?
Si la Máquina A es una caja de Windows, puede usar Plink (parte de PuTTY ) con el parámetro -m y ejecutará el script local en el servidor remoto.
plink root@MachineB -m local_script.sh
Si la Máquina A es un sistema basado en Unix, puede usar:
ssh root@MachineB 'bash -s' < local_script.sh
No debería tener que copiar el script al servidor remoto para ejecutarlo.
Esta es una pregunta antigua y la respuesta de Jason funciona bien, pero me gustaría agregar esto:
ssh user@host <<'ENDSSH'
#commands to run on remote host
ENDSSH
Esto también se puede usar con su y comandos que requieren la entrada del usuario. (tenga en cuenta el '
heredoc escapado)
Dado que esta respuesta sigue recibiendo tráfico, agregaría aún más información a este maravilloso uso de heredoc:
Puede anidar comandos con esta sintaxis, y esa es la única forma en que parece funcionar el anidamiento (de forma sensata)
ssh user@host <<'ENDSSH'
#commands to run on remote host
ssh user@host2 <<'END2'
# Another bunch of commands on another host
wall <<'ENDWALL'
Error: Out of cheese
ENDWALL
ftp ftp.example.com <<'ENDFTP'
test
test
ls
ENDFTP
END2
ENDSSH
De hecho, puedes tener una conversación con algunos servicios como telnet, ftp, etc. Pero recuerda que heredoc simplemente envía la entrada estándar como texto, no espera respuesta entre líneas.
¡Acabo de descubrir que puedes sangrar el interior con pestañas si usas <<-END
!
ssh user@host <<-'ENDSSH'
#commands to run on remote host
ssh user@host2 <<-'END2'
# Another bunch of commands on another host
wall <<-'ENDWALL'
Error: Out of cheese
ENDWALL
ftp ftp.example.com <<-'ENDFTP'
test
test
ls
ENDFTP
END2
ENDSSH
(Creo que esto debería funcionar)
Consulte también http://tldp.org/LDP/abs/html/here-docs.html
Además, no olvide escapar las variables si desea seleccionarlas del host de destino.
Esto me ha pillado en el pasado.
Por ejemplo:
user@host> ssh user2@host2 "echo \$HOME"
imprime /home/usuario2
mientras
user@host> ssh user2@host2 "echo $HOME"
imprime /home/usuario
Otro ejemplo:
user@host> ssh user2@host2 "echo hello world | awk '{print \$1}'"
imprime "hola" correctamente.
Esta es una extensión de la respuesta de YarekT para combinar comandos remotos en línea con el paso de variables ENV desde la máquina local al host remoto para que pueda parametrizar sus scripts en el lado remoto:
ssh user@host ARG1=$ARG1 ARG2=$ARG2 'bash -s' <<'ENDSSH'
# commands to run on remote host
echo $ARG1 $ARG2
ENDSSH
Esto me pareció excepcionalmente útil al mantenerlo todo en un solo script para que sea muy fácil de leer y mantener.
Por qué esto funciona. ssh admite la siguiente sintaxis:
ssh usuario@host comando_remoto
En bash podemos especificar variables de entorno para definir antes de ejecutar un comando en una sola línea como esta:
ENV_VAR_1='valor1' ENV_VAR_2='valor2' bash -c 'echo $ENV_VAR_1 $ENV_VAR_2'
Eso facilita la definición de variables antes de ejecutar un comando. En este caso, echo es el comando que estamos ejecutando. Todo lo anterior a echo define variables de entorno.
Entonces combinamos esas dos características y la respuesta de YarekT para obtener:
ssh usuario@host ARG1=$ARG1 ARG2=$ARG2 'bash -s' <<'ENDSSH'...
En este caso, configuramos ARG1 y ARG2 con valores locales. Enviando todo después de usuario@host como comando_remoto. Cuando la máquina remota ejecuta el comando ARG1 y ARG2, se configuran los valores locales, gracias a la evaluación de la línea de comando local, que define las variables de entorno en el servidor remoto y luego ejecuta el comando bash -s usando esas variables. Listo.