¿Cómo hacer ssh con un tiempo de espera en un script?

173

Estoy ejecutando un script que se conecta a través de SSH sin contraseña en un host remoto. Quiero establecer un tiempo de espera, de modo que si el host remoto tarda un tiempo infinito en ejecutarse, quiero salir de esa sesión ssh y continuar otras líneas en mi script sh.

¿Alguna idea de cómo hacerlo?

usuario57421
fuente
Esto probablemente debería cerrarse para estar en línea con el cierre de un duplicado completo de esta forma de disminuir el valor de tiempo de espera de conexión ssh [cerrado]
Murmel
Si redirigió aquí solo para "permanecer más tiempo en su sshsesión" (pregunta "¿Cómo aumentar el tiempo de espera de la conexión SSH?"), Este es el lugar equivocado . La respuesta está en este enlace sobre ssh-timeout .
Peter Krauss

Respuestas:

288
ssh -o ConnectTimeout=10  <hostName>

Donde 10 es tiempo en segundos. Este tiempo de espera se aplica solo a la creación de la conexión.

usuario57421
fuente
44
ConnectTimeout solo establece un tiempo de espera en la configuración de la conexión, ¿verdad?
Aurélien Ooms
10
En realidad, esto no funciona para "el host remoto está tardando un tiempo infinito en ejecutarse": "ssh -o ConnectTimeout = 5 host 'sleep 10'" espera 10 segundos, no 5.
Ferry Boender
109

Usa el -o ConnectTimeouty -o BatchMode=yes -o StrictHostKeyChecking=no.

ConnectTimeout evita que el script se cuelgue, BatchMode evita que se cuelgue con Host unknown, YES para agregar a known_hosts, y StrictHostKeyChecking agrega la huella digital automáticamente.

**** NOTA **** El "StrictHostKeyChecking" solo estaba destinado a redes internas en las que confía en sus hosts. Dependiendo de la versión del cliente SSH, el "¿Está seguro de que desea agregar su huella digital" puede hacer que el cliente se cuelgue indefinidamente (principalmente versiones antiguas que se ejecutan en AIX). La mayoría de las versiones modernas no sufren este problema. Si tiene que lidiar con huellas digitales con varios hosts, le recomiendo mantener el archivo known_hosts con algún tipo de herramienta de administración de configuración como puppet / ansible / chef / salt / etc.

Doug
fuente
11
No solo -o StrictHostKeyChecking=nono aborda la cuestión, sino que es una idea terrible si te preocupa la seguridad, que podría ser la razón por la que estás usando SSH en primer lugar.
Dolph
9
Es bueno señalar las posibles implicaciones de seguridad de -o StrictHostKeyChecking = no. Sin embargo, evitará que el script se cuelgue durante la ejecución.
Doug
2
¡¡¡¡ADVERTENCIA!!!! Como escribió @Dolph, NO lo use StrictHostKeyChecking=nosi le preocupa la seguridad. @Doug: el script no se bloqueará: solo insistirá en que envíe ssh al host remoto manualmente la primera vez, para que conozca el host. Pero te protegerá contra los ataques MITM. Edite esta respuesta para reflejar esto, ya que es un consejo muy peligroso tal como está. Y ni siquiera fue pedido.
johndodo
2
Actualicé mi respuesta. Desde mi experiencia, puede hacer que algunos clientes se cuelguen.
Doug
50

prueba esto:

timeout 5 ssh user@ip

timeout ejecuta el comando ssh (con args) y envía un SIGTERM si ssh no regresa después de 5 segundos. Para obtener más detalles sobre el tiempo de espera, lea este documento: http://man7.org/linux/man-pages/man1/timeout.1.html

o puedes usar el parámetro de ssh:

ssh -o ConnectTimeout=3 user@ip
Lee HoYo
fuente
44
Si está buscando este comando en una Mac, intente brew install coreutilsy luego use gtimeout (fuente: stackoverflow.com/questions/3504945/timeout-command-on-mac-os-x ).
larcher
3
Esto puede no hacer lo que quieres. Considere el comando timeout 3s ssh user@server 'sleep 5; echo blarg >> /tmp/blarg' Esto mata el proceso en el lado del cliente SSH, pero / tmp / blarg aún se modifica en el servidor remoto. Esto significa que si está ejecutando un trabajo fuera de control intensivo de CPU en el servidor remoto, perderá los procesos.
Jamie Davis
1
@JamieDavis ¿qué pasa con ssh user @ server 'timeout 5s sleep 10'?
FilipR
18

También puedes conectarte con la bandera

-o ServerAliveInterval = <segundos>
entonces el cliente SSH enviará un paquete nulo al servidor cada <secs>segundo, solo para mantener viva la conexión. En Linux, esto también se puede configurar globalmente en /etc/ssh/ssh_configo por usuario ~/.ssh/config.

Patrizio Bertoni
fuente
44
Eso suena como lo contrario de lo que pide la pregunta.
Davor Cubranic
1

Si todo lo demás falla (incluso no tener el timeoutcomando), el concepto en este script de shell funcionará:

 #!/bin/bash
 set -u
 ssh $1 "sleep 10 ; uptime" > /tmp/outputfile 2>&1 & PIDssh=$!
 Count=0
 while test $Count -lt 5 && ps -p $PIDssh > /dev/null
 do
    echo -n .
    sleep 1
    Count=$((Count+1))
 done
 echo ""

 if ps -p $PIDssh > /dev/null
 then
    echo "ssh still running, killing it"
    kill -HUP $PIDssh
 else
    echo "Exited"
 fi
Philip Kearns
fuente
0

Bueno, podría usar nohup para ejecutar lo que esté ejecutando en 'modo sin bloqueo'. Por lo tanto, puede seguir comprobando si lo que se suponía que debía ejecutarse, se ejecutó, de lo contrario, salga.

nohup ./my-script-that-may-take-long-to-finish.sh &
./check-if-previous-script-ran-or-exit.sh
echo "El script finalizó el 15 de febrero de 2011 a las 9:20 a.m."> /tmp/done.txt

Entonces, en el segundo, simplemente verifica si el archivo existe.

Eduardo
fuente
Tiene sentido. pero, el script que se está ejecutando me da algo de salida, que se muestra en la consola ... ¿cómo verificar si mi script anterior se ejecutó o salió? PS O algo más ?
user57421
Bueno, podrías hacer que ese script cree un archivo cuando haya terminado. He agregado el comentario a la respuesta ... grrr
Eduardo