servidor script remoto para mediante ejecutar desde como comandos comando automatizado shell ssh sysadmin remote-execution

remoto - ¿Cómo usar SSH para ejecutar un script de shell en una máquina remota?



script en bash para ejecutar un comando remoto mediante ssh (12)

Tengo que ejecutar un script de shell (windows / Linux) en una máquina remota.

Tengo SSH configurado en la máquina A y 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 una manera de ejecutar hacer esto usando plink / ssh?


Además, no olvide escapar de las variables si desea recogerlas del host de destino.

Esto me ha atrapado 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.


Comencé a usar Fabric para operaciones más sofisticadas. Fabric requiere Python y un par de otras dependencias, pero solo en la máquina cliente. El servidor solo necesita ser un servidor ssh. Considero que esta herramienta es mucho más poderosa que los scripts de shell que se transfieren a SSH, y vale la pena la configuración (especialmente si te gusta la programación en Python). Fabric maneja los scripts que se ejecutan en múltiples hosts (o hosts de ciertos roles), ayuda a facilitar las operaciones idempotentes (como agregar una línea a un script de configuración, pero no si ya está allí), y permite la construcción de lógica más compleja (como Python) el idioma puede proporcionar).


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

Encontré esto excepcionalmente útil al mantenerlo todo en una secuencia de comandos, por lo que es muy fácil de leer y mantener.

¿Por qué esto funciona? ssh soporta la siguiente sintaxis:

ssh user @ host remote_command

En bash, podemos especificar variables de entorno para definir antes de ejecutar un comando en una sola línea, de esta manera:

ENV_VAR_1 = ''value1'' ENV_VAR_2 = ''value2'' 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 nuestro comando que estamos ejecutando. Todo antes del eco define variables de entorno.

Así que 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, estamos configurando ARG1 y ARG2 a valores locales. Enviando todo después de user @ host como el remote_command. Cuando la máquina remota ejecuta el comando ARG1 y ARG2 se establecen los valores locales, gracias a la evaluación de la línea de comandos local, que define las variables de entorno en el servidor remoto, luego ejecuta el comando bash -s utilizando esas variables. Voila


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 utilizar con su y comandos que requieren la entrada del usuario. (nota el '' heredoc escapado)

Edit: Ya que esta respuesta sigue recibiendo bits de tráfico, agregaría aún más información a este maravilloso uso de heredoc:

Puede anidar los comandos con esta sintaxis, y esa es la única forma en que el anidamiento parece funcionar (de una manera sana)

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.secureftp-test.com <<''ENDFTP'' test test ls ENDFTP END2 ENDSSH

Realmente puedes tener una conversación con algunos servicios como telnet, ftp, etc. Pero recuerda que heredoc simplemente envía el stdin como texto, no espera respuesta entre líneas.

Edición: acabo de descubrir que puedes sangrar las partes interiores 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.secureftp-test.com <<-''ENDFTP'' test test ls ENDFTP END2 ENDSSH

(Creo que esto debería funcionar)

También vea http://tldp.org/LDP/abs/html/here-docs.html


Esta secuencia de comandos bash hace ssh en una máquina remota de destino, y ejecuta algún comando en la máquina remota, no olvide instalar expect antes de ejecutarlo (en Mac brew install expect )

#!/usr/bin/expect set username "enterusenamehere" set password "enterpasswordhere" set hosts "enteripaddressofhosthere" spawn ssh $username@$hosts expect "$username@$hosts''s password:" send -- "$password/n" expect "$" send -- "somecommand on target remote machine here/n" sleep 5 expect "$" send -- "exit/n"


Intente ejecutar ssh user@remote sh ./script.unx .


La respuesta aquí ( https://.com/a/2732991/4752883 ) funciona muy bien si está intentando ejecutar un script en una máquina Linux remota usando plink o ssh . Funcionará si el script tiene varias líneas en linux .

** Sin embargo, si está intentando ejecutar un script por lotes ubicado en una máquina linux/windows local y su máquina remota es Windows , y consta de varias líneas usando **

plink root@MachineB -m local_script.bat

no funciona

Solo se ejecutará la primera línea del script. Esta es probablemente una limitación de plink .

Solución 1:

Para ejecutar un script por lotes multilínea (especialmente si es relativamente simple, que consta de unas pocas líneas):

Si su script de lote original es el siguiente

cd C:/Users/ipython_user/Desktop python filename.py

puede combinar las líneas usando el separador "&&" de la siguiente manera en su archivo local_script.bat : https://.com/a/8055390/4752883 :

cd C:/Users/ipython_user/Desktop && python filename.py

Después de este cambio, puede ejecutar el script como se indica aquí en @ JasonR.Coombs: https://.com/a/2732991/4752883 con:

`plink root@MachineB -m local_script.bat`

Solución 2:

Si su secuencia de comandos por lotes es relativamente complicada, puede ser mejor usar una secuencia de comandos por lotes que encapsule el comando plink y siga las indicaciones de @Martin https://.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


Primero, copie el script a la Máquina B usando scp

[user @ machineA] $ scp / path / to / script user @ machineB: / home / user / path

Entonces, simplemente ejecuta el script

[usuario @ máquinaA] $ ssh usuario @ máquinaB "/ home / usuario / ruta / script"

Esto funcionará si ha dado permiso ejecutable a la secuencia de comandos.


Si la Máquina A es un cuadro 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.


Suponiendo que quiere decir que quiere hacer esto automáticamente desde una máquina "local", sin iniciar sesión manualmente en la máquina "remota", debe buscar una extensión TCL conocida como Expect, está diseñada precisamente para este tipo de situación. La página de inicio que se muestra a continuación parece un poco horrible, pero no dejes que eso te disuada; También proporcioné un enlace a un script para iniciar sesión / interactuar a través de SSH.

http://expect.nist.gov/

http://bash.cyberciti.biz/security/expect-ssh-login-script/


si quieres ejecutar un comando como este temp=`ls -a` echo $temp comando temp=`ls -a` echo $temp `causará errores.

El siguiente comando solucionará este problema ssh user@host '''''' temp=`ls -a` echo $temp ''''''


<hostA_shell_prompt>$ ssh user@hostB "ls -la"

Eso le solicitará la contraseña, a menos que haya copiado la clave pública de su usuario hostA al archivo authorized_keys en la página principal del directorio del usuario .ssh. Eso permitirá la autenticación sin contraseña (si se acepta como un método de autenticación en la configuración del servidor ssh)