Jak uruchomić polecenie ssh, dopóki się nie powiedzie?


28

Czasami ponownie uruchamiam urządzenie i muszę się z sshpowrotem podłączyć, gdy będzie gotowe.

Chcę uruchamiać polecenie ssh co 5 sekund, aż polecenie się powiedzie.

Moja pierwsza próba:

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

W jaki sposób mogę to zrobić?


Czy chcesz interaktywnej sesji SSH?
Nikt

@Nikt tak, ja tak
Philip Kirkbride,

Ok, najpierw pomyślałem, że mój pomysł nie zadziała interaktywnie, ale krótki test wykazał, że tak, więc i tak napisałem odpowiedź. :)
Nikt

Odpowiedzi:


30

Inną opcją byłoby użycie until.

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

Jeśli robisz to wielokrotnie dla wielu hostów, umieść to w swojej funkcji ~/.bashrc.

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

1
dzięki, zamierzam użyć skryptu powtarzania, ale $zamiast monitu :-)
Philip Kirkbride

14
Warto zauważyć, że sshmożna wyjść ze statusem niezerowym po udanym połączeniu, jeśli sesja zakończy się czymś zewnętrznym, w którym to przypadku skrypt podejmie próbę ponownego połączenia. Może to być pożądany efekt uboczny.
Austin Hemmelgarn

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

!!Powtórzyć ostatnie polecenie.


4
Kreatywne wykorzystanie historii muszli! +1
David Foerster

15

OpenSSH ma ConnectionAttemptsustawienie, które robi prawie to, co chcesz. Wartość domyślna to 1, ale można ją zmienić w ssh_configwierszu polecenia lub w wierszu poleceń:

ssh -o 'ConnectionAttempts 10' ...

Niestety nie można dostosować interwału próby, który jest ustalony na 1 sekundę, ale można dostosować limit czasu próby połączenia ConnectTimeout(w sekundach) w ten sam sposób.


To chyba nie działa dla mnie: /
Freedo

@ Freedo: Czy mógłbyś wyjaśnić, co dokładnie próbowałeś, a co nie działało? Lepiej byłoby też napisać nowe pytanie dotyczące twojego problemu. Proszę o zwrócenie na mnie uwagi poprzez link w komentarzach.
David Foerster,

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

2
Lub, jeśli nie chcemy, aby rzeczywiście zalogować dopóki usługa jest w górze, while ! nc -w5 -z host.example.com 22; do [...].
DopeGhoti

4

autosshutrzymuje sesje ssh przy życiu. Przy odpowiednich parametrach możesz go również uruchomić, gdy połączenie jest obecnie niemożliwe i będzie próbował, dopóki się nie powiedzie. Działa to dobrze, ale jeśli chcesz, aby część re Connect działała dobrze z interaktywnymi sesjami, musisz połączyć ją z screenlub równoważną.

Polecam to:

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

Ale zobacz jego stronę podręcznika, aby uzyskać szczegółowe informacje. Przy powyższych parametrach autosshspróbuje uruchomić ssh co AUTOSSH_POLLsekundę, AUTOSSH_GATETIME=0sprawi, że spróbuje ponownie, jeśli pierwsza próba się nie powiedzie (więc na pewno to, czego chcesz), -M 0wyłącza sprawdzanie połączenia przez autossh, wszystkie późniejsze opcje są przekazywane do ssh. Obie -oopcje powodują wyjście ssh, jeśli połączenia spadną na więcej niż 5 sekund.


2

Ryzykując po prostu rzuceniem kodu na odpowiedź, ten skrypt działa dla mnie codziennie. Nazywam to resshi można go używać tak prosto ressh {hostname}lub ostrożnie,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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.