Hacer que ssh ejecute un comando en segundo plano en la máquina de destino

StackOverflow https://stackoverflow.com/questions/29142

  •  09-06-2019
  •  | 
  •  

Pregunta

Esta es una pregunta de seguimiento a la ¿Cómo se usa ssh en un script de shell? pregunta.Si quiero ejecutar un comando en la máquina remota que se ejecuta en segundo plano en esa máquina, ¿cómo hago para que regrese el comando ssh?Cuando intento incluir simplemente el signo comercial (&) al final del comando, simplemente se bloquea.La forma exacta del comando se ve así:

ssh user@target "cd /some/directory; program-to-execute &"

¿Algunas ideas?Una cosa a tener en cuenta es que los inicios de sesión en la máquina de destino siempre producen un banner de texto y tengo SSH Claves configuradas para que no se requiera contraseña.

¿Fue útil?

Solución

Tuve este problema en un programa que escribí hace un año; resulta que la respuesta es bastante complicada.Necesitará usar nohup así como la redirección de salida, como se explica en el artículo de Wikipedia sobre nohup, copiado aquí para su comodidad.

Los trabajos de antecedentes de nohuping son útiles, por ejemplo, cuando se registran a través de SSH, ya que los trabajos de fondo pueden hacer que el shell se quede en el inicio de sesión debido a una condición de carrera [2].Este problema también se puede superar redirigiendo las tres corrientes de E/S:

nohup myprogram > foo.out 2> foo.err < /dev/null &

Otros consejos

Esta ha sido la forma más limpia de hacerlo para mí: -

ssh -n -f user@host "sh -c 'cd /whereever; nohup ./whatever > /dev/null 2>&1 &'"

Lo único que se ejecuta después de esto es el comando real en la máquina remota.

Redirigir fd's

La salida debe redirigirse con &>/dev/null que redirige tanto stderr como stdout a /dev/null y es sinónimo de >/dev/null 2>/dev/null o >/dev/null 2>&1.

paréntesis

La mejor manera es usar sh -c '( ( command ) & )' donde el comando es cualquier cosa.

ssh askapache 'sh -c "( ( nohup chown -R ask:ask /www/askapache.com &>/dev/null ) & )"'

Concha Nohup

También puedes usar nohup directamente para iniciar el shell:

ssh askapache 'nohup sh -c "( ( chown -R ask:ask /www/askapache.com &>/dev/null ) & )"'

Buen lanzamiento

Otro truco es usar nice para iniciar el comando/shell:

ssh askapache 'nice -n 19 sh -c "( ( nohup chown -R ask:ask /www/askapache.com &>/dev/null ) & )"'

Solo quería mostrar un ejemplo práctico que puedes cortar y pegar:

ssh REMOTE "sh -c \"(nohup sleep 30; touch nohup-exit) > /dev/null &\""

Si no puede/no puede mantener la conexión abierta, puede usar pantalla, si tiene los derechos para instalarlo.

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 desconectar la sesión de pantalla: Ctrl-a d

Para enumerar sesiones de pantalla:

screen -ls

Para volver a adjuntar una sesión:

screen -d -r remote-command

Tenga en cuenta que la pantalla también puede crear múltiples shells dentro de cada sesión.Un efecto similar se puede lograr con 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 la sesión tmux: Ctrl-b d

Para enumerar sesiones de pantalla:

tmux list-sessions

Para volver a adjuntar una sesión:

tmux attach <session number>

La clave de control tmux predeterminada, 'Ctrl-b', es algo difícil de usar, pero hay varios ejemplos de configuraciones de tmux que se incluyen con tmux y que puedes probar.

La forma más rápida y sencilla es utilizar el comando 'at':

ssh usuario@objetivo "ahora -f /home/foo.sh"

Creo que tendrás que combinar un par de estas respuestas para obtener lo que deseas.Si usa nohup junto con el punto y coma y envuelve todo entre comillas, obtendrá:

ssh user@target "cd /some/directory; nohup myprogram > foo.out 2> foo.err < /dev/null"

lo que parece funcionar para mí.Con nohup, no es necesario agregar & al comando que se ejecutará.Además, si no necesita leer ninguno de los resultados del comando, puede usar

ssh user@target "cd /some/directory; nohup myprogram > /dev/null 2>&1"

para redirigir toda la salida a /dev/null.

Esto funcionó para mí muchas veces:

ssh -x remoteServer "cd yourRemoteDir; ./yourRemoteScript.sh </dev/null >/dev/null 2>&1 & " 

En realidad, cada vez que necesito ejecutar un comando en una máquina remota que es complicado, me gusta poner el comando en un script en la máquina de destino y simplemente ejecutar ese script usando ssh.

Por ejemplo:

# simple_script.sh (located on remote server)

#!/bin/bash

cat /var/log/messages | grep <some value> | awk -F " " '{print $8}'

Y luego ejecuto este comando en la máquina fuente:

ssh user@ip "/path/to/simple_script.sh"

Estaba intentando hacer lo mismo, pero con la complejidad añadida de que intentaba hacerlo desde Java.Entonces, en una máquina que ejecuta Java, estaba intentando ejecutar un script en otra máquina, en segundo plano (con nohup).

Desde la línea de comando, esto es lo que funcionó:(Es posible que no necesite el "-i keyFile" si no lo necesita para enviarlo por ssh al host)

ssh -i keyFile user@host bash -c "\"nohup ./script arg1 arg2 > output.txt 2>&1 &\""

Tenga en cuenta que en mi línea de comando, hay un argumento después de "-c", que está entre comillas.Pero para que funcione en el otro extremo, todavía necesita las comillas, así que tuve que poner comillas escapadas dentro.

Desde Java, esto es lo que funcionó:

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.

Fue necesario un poco de prueba y error para que esto funcionara, pero parece funcionar bien ahora.

Puedes hacerlo así...

sudo /home/script.sh -opt1 > /tmp/script.out &

Me pareció muy conveniente tener un remoto sesión tmux usando el tmux new -d <shell cmd> sintaxis como esta:

ssh someone@elsewhere 'tmux new -d sleep 600'

Esto iniciará una nueva sesión el elsewhere El comando host y ssh en la máquina local volverá al shell casi al instante.Luego puede enviar ssh al host remoto y tmux attach a esa sesión.Tenga en cuenta que no hay nada sobre la ejecución local de tmux, ¡solo remota!

Además, si desea que su sesión persista una vez finalizado el trabajo, simplemente agregue un iniciador de shell después de su comando, pero no olvide incluirlo entre comillas:

ssh someone@elsewhere 'tmux new -d "~/myscript.sh; bash"'

Creo que esto es lo que necesitas:Al principio necesitas instalar sshpass en su máquina.entonces puedes escribir tu propio 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

Primero siga este procedimiento:

Inicie sesión en A como usuario a y genere un par de claves de autenticación.No ingrese una frase de contraseña:

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

Ahora use ssh para crear un directorio ~/.ssh como usuario b en B.(Es posible que el directorio ya exista, lo cual está bien):

a@A:~> ssh b@B mkdir -p .ssh
b@B's password: 

Finalmente agregue la nueva clave pública de a a b@B:.ssh/authorized_keys e ingrese la contraseña de b por última vez:

a@A:~> cat .ssh/id_rsa.pub | ssh b@B 'cat >> .ssh/authorized_keys'
b@B's password: 

A partir de ahora puedes iniciar sesión en B como b desde A como a sin contraseña:

a@A:~> ssh b@B

entonces esto funcionará sin ingresar una contraseña

ssh b@B "cd /algún/directorio;programa a ejecutar &"

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top