Come eseguire il comando ssh fino a quando non è riuscito?


28

A volte riavvio un dispositivo e devo riaccedere sshquando è pronto.

Voglio eseguire il comando ssh ogni 5 secondi fino a quando il comando non riesce.

Il mio primo tentativo:

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

Come posso fare questo?


Vuoi una sessione SSH interattiva?
Nessuno il

@Nessuno sì, lo faccio
Philip Kirkbride,

Ok, inizialmente ho pensato che la mia idea non avrebbe funzionato in modo interattivo, ma un breve test ha dimostrato che lo fa, quindi ho scritto una risposta comunque. :)
Nessuno il

Risposte:


30

Un'altra opzione sarebbe quella di utilizzare until.

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

Se lo fai ripetutamente per un numero di host, mettilo in una funzione nel tuo ~/.bashrc.

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

1
grazie, userò lo script di ripetizione ma con $invece del prompt :-)
Philip Kirkbride,

14
Vale la pena notare che sshpuò uscire con uno stato diverso da zero dopo essersi connessi correttamente se qualcosa di esterno alla connessione termina la sessione, nel qual caso lo script tenterà di riconnettersi. Questo può o meno essere un effetto collaterale desiderabile.
Austin Hemmelgarn,

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

Il !!per ripetere l'ultimo comando.


4
Uso creativo della storia della shell! +1
David Foerster,

15

OpenSSH ha ConnectionAttemptsun'impostazione che fa quasi quello che vuoi. Il valore predefinito è 1 ma è possibile modificarlo nella ssh_configo nella riga di comando:

ssh -o 'ConnectionAttempts 10' ...

Purtroppo non è possibile regolare l'intervallo di tentativo fissato a 1 secondo, ma è possibile regolare il timeout del tentativo di connessione ConnectTimeout(in secondi) nello stesso modo.


Questo non sembra funzionare per me: /
Freedo il

@Freedo: Potresti spiegare cosa hai provato esattamente e cosa esattamente non ha funzionato? Inoltre, sarebbe probabilmente meglio scrivere una nuova domanda sul tuo problema. Sei il benvenuto per attirare la mia attenzione su di esso attraverso un link nei commenti.
David Foerster,

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

2
O, se non si vuole effettuare il log in realtà fino a quando il servizio è alto, while ! nc -w5 -z host.example.com 22; do [...].
DopeGhoti,

4

autosshmantiene vive le sessioni ssh. Con i parametri giusti puoi anche avviarlo quando è attualmente impossibile connettersi e proverà fino a quando non avrà successo. Questo funziona bene, ma se si desidera che il re parte di connessione al lavoro bene con sessioni interattive di cui ha bisogno per combinarlo con screeno equivalente.

Consiglio questo:

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

Ma vedi la sua pagina man per i dettagli. Con i parametri sopra, autosshproverò ad avviare ssh ogni AUTOSSH_POLLsecondo, lo AUTOSSH_GATETIME=0farà riprovare se il primo tentativo fallisce (quindi sicuramente quello che vuoi), -M 0disabilita il controllo della connessione tramite autossh, tutte le opzioni successive vengono passate a ssh. Le due -oopzioni fanno uscire ssh se le connessioni scendono per più di 5 secondi.


2

A rischio di lanciare semplicemente un codice per una risposta, questo script funziona per me quotidianamente. Io lo chiamo resshe può essere usato semplicemente ressh {hostname}o con cura,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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.