¿Cómo ejecutar el comando ssh hasta tener éxito?


28

A veces reinicio un dispositivo y necesito sshvolver a conectarlo cuando esté listo.

Quiero ejecutar el comando ssh cada 5 segundos hasta que el comando tenga éxito.

Mi primer intento

watch -n5 ssh me@device.local && exit 1

¿Cómo puedo hacer esto?


¿Quieres una sesión SSH interactiva?
Nadie

@ Nadie, sí lo hago
Philip Kirkbride

Ok, primero pensé que mi idea no funcionaría interactivamente, pero una prueba corta mostró que sí, así que escribí una respuesta de todos modos. :)
Nadie

Respuestas:


30

Otra opción sería usar until.

until ssh me@device.local; do
    sleep 5
done

Si hace esto repetidamente para varios hosts, póngalo en una función en su ~/.bashrc.

repeat()
{
read -p "Enter the hostname or IP of your server :" servername
until ssh $servername; do
    sleep 5
done
}

1
gracias, voy a usar la secuencia de comandos de repetición pero con en $lugar del indicador :-)
Philip Kirkbride

14
Vale la pena señalar que sshpuede salir con un estado distinto de cero después de haberse conectado con éxito si algo externo a la conexión termina la sesión, en cuyo caso ese script intentará volver a conectarse. Esto puede o no ser un efecto secundario deseable.
Austin Hemmelgarn

17
ssh me@device.local
until !!; do sleep 5 ; done

El !!para repetir el último comando.


44
¡Uso creativo de la historia de shell! +1
David Foerster

15

OpenSSH tiene una ConnectionAttemptsconfiguración que hace casi lo que quieres. El valor predeterminado es 1, pero puede cambiarlo en ssh_configo en la línea de comandos:

ssh -o 'ConnectionAttempts 10' ...

Desafortunadamente, no puede ajustar el intervalo de intento que se fija en 1 segundo, pero puede ajustar el tiempo de espera del intento de conexión ConnectTimeout(en segundos) de la misma manera.


Esto no parece estar funcionando para mí: /
Freedo

@Freedo: ¿Podría explicar qué intentó exactamente y qué no funcionó exactamente? Además, probablemente sea mejor escribir una nueva pregunta sobre su problema. Puede llamar mi atención a través de un enlace en los comentarios.
David Foerster

14
while ! ssh user@host.example.com true; do
    sleep 5
done; echo "Host is back up at $(date)!"

2
O, si no desea iniciar sesión hasta que el servicio esté activo while ! nc -w5 -z host.example.com 22; do [...],.
DopeGhoti

4

autosshmantiene vivas las sesiones ssh. Con los parámetros correctos, también puede iniciarlo cuando actualmente es imposible conectarse y lo intentará hasta que tenga éxito. Esto funciona bien, pero si quieres la re parte conectarse con el trabajo muy bien con sesiones interactivas que necesitará para combinarlo con screeno equivalente.

Recomiendo esto

AUTOSSH_POLL=5 AUTOSSH_GATETIME=0 autossh -M 0 -o ServerAliveInterval=5 -o ServerAliveCountMax=1 user@host

Pero vea su página de manual para más detalles. Con los parámetros anteriores, autosshintentará iniciar ssh cada AUTOSSH_POLLsegundo, AUTOSSH_GATETIME=0lo intenta de nuevo si falla el primer intento (así que definitivamente lo que desea), -M 0deshabilita la comprobación de conexión mediante autossh, todas las opciones posteriores se pasan a ssh. Las dos -oopciones hacen que ssh salga si las conexiones caen durante más de 5 segundos.


2

A riesgo de arrojar código a una respuesta, este script funciona para mí diariamente. Lo llamo resshy se puede usar tan simple como ressh {hostname}o con cuidado,ressh -S {session_name} {hostname}

#!/bin/bash
#
# Repeatedly attempt to reconnect to a remote ssh server
########################################################################
#
prefix="${0/*\/}"
port=
session=
action=ssh              # How to connect remotely

while getopts 'l:Lp:P:S:' OPT
do
    case "$OPT" in
        l)      [[ s == "$OPTARG" ]] && action=list ;;
        L)      action=list ;;
        [Pp])   port="$OPTARG" ;;
        S)      session="$OPTARG";; ## ; [[ $session =~ ^[0-9]+$ ]] && session="${prefix}-$session" ;;
    esac
done
shift $(($OPTIND - 1))

host="$1"
shift

if [[ -z "$host" ]]
then
    echo "ERROR: Missing hostname" >&2
    exit 1
fi


if [[ list == "$action" ]]
then
    ssh ${port:+-p $port} "$host" "screen -ls"
    exit 0
fi

# Connect repeatedly to the target host system
#
[[ -z "$session" ]] && session="${prefix}-$$.$host"

while :
do
    ssh -tt ${port:+-p $port} "$host" "screen -dr $session || screen -S $session $*"
    ss=$?
    [[ 0 -eq $ss ]] && break

    [[ 255 -eq $ss ]] && sleep 4
    sleep 1
    echo "Reconnecting to session $session on $host..."
done


# All done
#
exit 0
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.