Bagaimana menjalankan perintah ssh sampai berhasil?

28

Terkadang saya me-restart perangkat dan harus sshkembali ketika sudah siap.

Saya ingin menjalankan perintah ssh setiap 5 detik hingga perintah berhasil.

Upaya pertama saya:

watch -n5 ssh [email protected] && exit 1

Bagaimana saya bisa melakukan ini?

Philip Kirkbride
sumber
Apakah Anda ingin sesi SSH interaktif?
Tidak ada yang
@Tidak ada yang saya lakukan
Philip Kirkbride
Ok, saya pertama kali berpikir ide saya tidak akan bekerja secara interaktif, tetapi tes singkat menunjukkan bahwa itu jadi saya tetap menulis jawaban. :)
Tidak ada yang

Jawaban:

30

Pilihan lain adalah menggunakan until.

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

Jika Anda melakukan ini berulang kali untuk sejumlah host, masukkan ke dalam fungsi Anda ~/.bashrc.

repeat()
{
read -p "Enter the hostname or IP of your server :" servername
until ssh $servername; do
    sleep 5
done
}
Pemburu. Thompson
sumber
1
terima kasih, saya akan menggunakan skrip ulangi tetapi dengan $alih - alih prompt :-)
Philip Kirkbride
14
Perlu dicatat bahwa sshdapat keluar dengan status non-nol setelah berhasil terhubung jika sesuatu eksternal ke koneksi mengakhiri sesi, dalam hal ini skrip yang akan berusaha untuk menyambung kembali. Ini mungkin atau mungkin bukan efek samping yang diinginkan.
Austin Hemmelgarn
17
ssh me@device.local
until !!; do sleep 5 ; done

Untuk !!mengulangi perintah terakhir.

GAD3R
sumber
4
Penggunaan kreatif dari riwayat shell! +1
David Foerster
15

OpenSSH memiliki ConnectionAttemptspengaturan yang melakukan hampir semua yang Anda inginkan. Standarnya adalah 1 tetapi Anda dapat mengubahnya di ssh_configatau di baris perintah:

ssh -o 'ConnectionAttempts 10' ...

Sayangnya Anda tidak dapat menyesuaikan interval upaya yang ditetapkan pada 1 detik, tetapi Anda dapat menyesuaikan batas waktu upaya koneksi ConnectTimeout(dalam detik) dengan cara yang sama.

David Foerster
sumber
Ini sepertinya tidak berfungsi untuk saya: /
Freedo
@Freedo: Bisakah Anda jelaskan apa yang sebenarnya Anda coba dan apa yang sebenarnya tidak berhasil? Juga, kemungkinan akan lebih baik untuk menulis pertanyaan baru tentang masalah Anda. Anda dapat menarik perhatian saya melalui tautan di komentar.
David Foerster
14
while ! ssh user@host.example.com true; do
    sleep 5
done; echo "Host is back up at $(date)!"
DopeGhoti
sumber
2
Atau, jika Anda tidak ingin benar-benar masuk sampai layanannya selesai while ! nc -w5 -z host.example.com 22; do [...],.
DopeGhoti
4

autosshmembuat sesi ssh tetap hidup. Dengan parameter yang tepat Anda juga dapat meluncurkannya saat saat ini tidak memungkinkan untuk terhubung dan akan mencoba sampai berhasil. Ini berfungsi dengan baik, tetapi jika Anda ingin bagian yang terhubung kembali bekerja dengan baik dengan sesi interaktif Anda harus menggabungkannya screenatau setara.

Saya merekomendasikan ini:

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

Tetapi lihat halaman manualnya untuk detailnya. Dengan parameter di atas, autosshakan mencoba meluncurkan ssh setiap AUTOSSH_POLLdetik, AUTOSSH_GATETIME=0membuatnya mencoba lagi jika percobaan pertama gagal (jadi pasti apa yang Anda inginkan), -M 0menonaktifkan pemeriksaan koneksi dengan autossh, semua opsi nanti diteruskan ke ssh. Dua -oopsi membuat ssh keluar jika koneksi turun lebih dari 5s.

Tak seorangpun
sumber
2

Dengan risiko hanya melempar kode pada jawaban, skrip ini berfungsi untuk saya setiap hari. Saya menyebutnya resshdan dapat digunakan hanya sebagai ressh {hostname}, atau dengan hati-hati,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
roaima
sumber