¿Cómo puedo crear una conexión SSH persistente para "transmitir" comandos durante un período de tiempo?

9

Digamos que tengo una aplicación que se ejecuta en una PC que envía comandos a través de SSH a otra PC en la red (ambas máquinas que ejecutan Linux).

Por ejemplo, cada vez que sucede algo en el n. ° 1, quiero ejecutar una tarea en el n. ° 2. En esta configuración, tengo que crear una conexión SSH en cada comando.

¿Hay alguna manera simple de hacer esto con herramientas básicas de Unix sin programar aplicaciones cliente / servidor personalizadas? Básicamente, todo lo que quiero es establecer una conexión a través de SSH y luego enviar un comando tras otro.

Jakub Arnold
fuente

Respuestas:

12

No estoy seguro de si se puede usar en la producción, pero puede hacer algo como esto:

crear archivo en # 1

1> touch /tmp/commands

Luego ejecute el comando:

1> tail -f /tmp/commands | ssh [email protected]

Eso abrirá el archivo / tmp / comandos y comenzará a enviar su contenido al servidor xxxx (# 2) y lo ejecutará línea por línea

ahora, cada vez que sucede algo en el n. ° 1, haga lo siguiente:

1> echo "ls -l" >> /tmp/commands

o

1> echo "reboot" >> /tmp/commands

lo que agregue al archivo / tmp / comandos se enviará al n. ° 2 y se ejecutará. Solo asegúrese de no ejecutar nada interactivo o tratarlo de alguna manera.

Vitaly Nikolaev
fuente
Esto es exactamente lo que estaba buscando, una solución muy creativa :)
Jakub Arnold
55
Agregaría que debe usar tail -F, lo que detectará que el archivo ha sido reemplazado, por lo que cuando llegue a ser gigante, puede borrarlo y comenzar de nuevo con un nuevo archivo.
DerfK
3
@DerfK, alternativamente, mkfifo /tmp/commandsdebería ser una mejor solución
solotim
18

Persistencia automática con OpenSSH

También puede usar la ControlMasterfunción de OpenSSH, que abre un socket de dominio Unix para la primera conexión y reutiliza esta conexión en todas las llamadas posteriores.

Para habilitar la función, puede usarla -Mcomo el interruptor de línea de comando o habilitar la ControlMasteropción en su ~/.ssh/ssh_config, por ejemplo:

ControlMaster auto

Además, debe configurar el ControlPathuso de las siguientes líneas en su ~/.ssh/ssh_config:

Host *
   ControlPath ~/.ssh/master-%r@%h:%p

Para mantener una conexión persistente a un host, por ejemplo, si desea ejecutar un script que necesita establecer muchas conexiones ssh con el host, ninguno de los cuales persiste durante toda la vida útil del script, puede iniciar una conexión silenciosa por adelantado usando:

ssh -MNf remotehost

Cheerio, nesono

nesono
fuente
Accedí a la falla del servidor solo para hacer +1 en tu respuesta. ¡El tuyo funcionó!
Karma
ssh -Ninicia una sesión sin comando remoto, parece que no hay opciones correspondientes en ssh_config.
Jokester
2

En /etc/ssh/ssh_configagregar

# Send keep alive signal to remote sshd
ServerAliveInterval 60
Sandra
fuente
2

Si te encuentras mucho con este tipo de cosas, prueba Parallel . Es como dsh (shell distribuido) pero tiene algunas características interesantes como contar semáforos y se mantiene activamente.

De la documentación:

EJEMPLO: GNU Paralelo como sistema de colas / administrador de lotes

GNU Parallel puede funcionar como un simple sistema de cola de trabajos o como administrador de lotes. La idea es poner los trabajos en un archivo y hacer que GNU Parallel lea de eso continuamente. Como GNU Parallel se detendrá al final del archivo, usamos tail para continuar leyendo:

echo >jobqueue; tail -f jobqueue | parallel

Para enviar sus trabajos a la cola:

echo my_command my_arg >> jobqueue

Por supuesto, puede usar -S para distribuir los trabajos a computadoras remotas:

echo >jobqueue; tail -f jobqueue | parallel -S ..

Hay muchos buenos ejemplos que solo rascan la superficie. Aquí hay uno genial.

EJEMPLO: Distribución de trabajo a computadoras locales y remotas

Convierta * .mp3 a * .ogg ejecutando un proceso por núcleo de CPU en la computadora local y el servidor2:

  parallel --trc {.}.ogg -j+0 -S server2,: \
  'mpg321 -w - {} | oggenc -q0 - -o {.}.ogg' ::: *.mp3
Allen
fuente
0

sí, es posible con una tubería:

echo 'echo "hi"' | ssh -i my_private_key tester@host2

esto ejecutará el comando echo "hola" en host2

solo tiene que escribir un programa, que solo da los comandos (no olvide el;) y luego canalice esa salida a ssh

JMW
fuente
0

Es posible que desee usar un programa como dsh (Distributed SHell) que está hecho para hacer eso :) Después de configurarlo con nombres de host y configurar publickeya auth, puede usarlo para ejecutar comandos en varias máquinas en serie ("ejecutar en la máquina a luego ejecutar en la máquina b ") o en pararell (" ejecutar en todas las máquinas al mismo tiempo "). O simplemente hacer script

#!/bin/sh
ssh machine -- $@
exec $@
XANi
fuente
0

DESCARGO DE RESPONSABILIDAD: No puedo probar esto ahora, ya que estoy en una máquina Windows con bash pero sin ssh.

En un script bash, puedes hacer algo como esto:

exec 4> >(ssh --ssh-options-here user@host)

Y luego, para enviar comandos, escríbalos en FD 4.

echo 'echo hi' >&4

Si lo hace de esta manera, no puede acceder fácilmente a los resultados de los comandos, pero según su pregunta, no parece que sea necesario.

usuario253751
fuente