Як запустити команду ssh, поки це не вдалося?


28

Іноді перезавантажую пристрій і мені потрібно sshповернутися назад, коли воно буде готове.

Я хочу запускати команду ssh кожні 5 секунд, поки команда не буде успішною.

Моя перша спроба:

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

Як я можу це зробити?


Ви хочете інтерактивний сеанс SSH?
Ніхто

@Nobody так, що я
Філіп Кіркбрід

Гаразд, я спершу подумав, що моя ідея не працюватиме інтерактивно, але короткий тест показав, що це так, я все одно написав відповідь. :)
Ніхто

Відповіді:


30

Іншим варіантом буде використання until.

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

Якщо ви робите це неодноразово для декількох хостів, введіть його у свою функцію ~/.bashrc.

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

1
дякую, я буду використовувати сценарій повтору, але $замість підказки :-)
Philip Kirkbride

14
Варто зауважити, що sshпісля завершення сеансу завершення сеансу може завершити сеанс із ненульовим статусом, якщо щось зовнішнє для цього з'єднання припиняється, і в цьому випадку цей сценарій буде спробу знову підключитися. Це може бути або не бути бажаним побічним ефектом.
Остін Хеммельгарн


15

OpenSSH має a ConnectionAttempts налаштування, яке робить майже все, що ви хочете. За замовчуванням 1, але ви можете змінити його в ssh_configкомандному рядку або:

ssh -o 'ConnectionAttempts 10' ...

На жаль, ви не можете налаштувати інтервал спроби, який фіксується на 1 секунду, але ви можете скорегувати тайм-аут спроби з'єднання ConnectTimeout(у секундах) таким же чином.


Це, здається, не працює для мене: /
Freedo

@Freedo: Скажіть, будь ласка, що саме ви спробували, а що точно не вийшло? Крім того, було б, ймовірно, краще написати нове запитання щодо своєї проблеми. Ви можете звернути мою увагу на це через посилання в коментарях.
Девід Фоерстер

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

2
Або, якщо ви не хочете , щоб на самому ділі увійти , поки служба не вгору, while ! nc -w5 -z host.example.com 22; do [...].
DopeGhoti

4

autosshзберігає ssh сесії в живих. За допомогою правильних параметрів ви також можете запустити його, коли підключити наразі неможливо, і він буде намагатися, поки це не вдасться. Це прекрасно працює, але якщо ви хочете, щоб частина для повторного підключення гарно працювала з інтерактивними сеансами, вам потрібно буде комбінувати її screenабо еквівалент.

Я рекомендую це:

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

Але дивіться детальну сторінку сторінки. З перерахованими вище параметрами, autosshбуде намагатися запускати ssh кожні AUTOSSH_POLLсекунди, AUTOSSH_GATETIME=0змушує повторити спробу, якщо перша спроба не вдасться (так, безумовно, що ви хочете), -M 0відключає перевірку з’єднання за допомогою autossh, всі пізніші параметри передаються в ssh. Дві -oопції роблять ssh вихід, якщо з'єднання перестають більше 5 с.


2

Загрожуючи просто кинути код у відповідь, цей сценарій працює для мене щодня. Я називаю це, resshі його можна використовувати так само просто ressh {hostname}, або обережно,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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.