วิธีรันคำสั่ง ssh จนกว่าจะสำเร็จ


28

บางครั้งฉันรีสตาร์ทอุปกรณ์และจำเป็นต้องsshกลับเข้ามาใหม่เมื่อพร้อม

ฉันต้องการเรียกใช้คำสั่ง ssh ทุก 5 วินาทีจนกระทั่งคำสั่งสำเร็จ

ความพยายามครั้งแรกของฉัน:

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

ฉันจะทำสิ่งนี้ได้อย่างไร


คุณต้องการเซสชัน SSH เชิงโต้ตอบหรือไม่
ไม่มีใคร

@ ไม่มีใครใช่ฉันทำได้
Philip Kirkbride

ตกลงฉันแรกคิดว่าความคิดของฉันจะไม่ทำงานแบบโต้ตอบ แต่การทดสอบสั้น ๆ แสดงให้เห็นว่ามันเป็นดังนั้นฉันจึงเขียนคำตอบต่อไป :)
ไม่มีใคร

คำตอบ:


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
ขอบคุณฉันจะใช้สคริปต์ซ้ำ แต่ด้วย$แทนของพร้อม :-)
ฟิลิป Kirkbride

14
เป็นที่น่าสังเกตว่าsshสามารถออกจากสถานะไม่เป็นศูนย์หลังจากเชื่อมต่อได้สำเร็จหากมีสิ่งภายนอกที่เชื่อมต่อยกเลิกเซสชันซึ่งในกรณีนี้สคริปต์จะพยายามเชื่อมต่ออีกครั้ง นี่อาจเป็นหรือไม่เป็นผลข้างเคียงที่ต้องการ
Austin Hemmelgarn

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

The !!เพื่อทำซ้ำคำสั่งสุดท้าย


4
การใช้ประวัติเชลล์อย่างสร้างสรรค์! +1
David Foerster

15

OpenSSH มีการConnectionAttemptsตั้งค่าที่เกือบจะเป็นสิ่งที่คุณต้องการ ค่าเริ่มต้นคือ 1 แต่คุณสามารถเปลี่ยนในssh_configหรือในบรรทัดคำสั่ง:

ssh -o 'ConnectionAttempts 10' ...

น่าเสียดายที่คุณไม่สามารถปรับช่วงเวลาในการลองซึ่งกำหนดไว้ที่ 1 วินาที แต่คุณสามารถปรับการหมดเวลาในการพยายามเชื่อมต่อConnectTimeout(เป็นวินาที) ในแบบเดียวกัน


ดูเหมือนจะไม่ได้ผลสำหรับฉัน: /
Freedo

@ เฟรโด้: คุณช่วยอธิบายสิ่งที่คุณพยายามและสิ่งที่ไม่ได้ผล? และน่าจะดีกว่าถ้าคุณเขียนคำถามใหม่เกี่ยวกับปัญหาของคุณ คุณสามารถดึงดูดความสนใจของฉันผ่านลิงค์ aa ในความคิดเห็น
David Foerster

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

แต่ดูรายละเอียดเพิ่มเติมใน man page ของมัน ด้วยพารามิเตอร์ข้างต้น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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.