Làm thế nào để chạy lệnh ssh cho đến khi thành công?


28

Đôi khi tôi khởi động lại thiết bị và cần sshquay lại khi thiết bị đã sẵn sàng.

Tôi muốn chạy lệnh ssh cứ sau 5 giây cho đến khi lệnh thành công.

Nỗ lực đầu tiên của tôi:

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

Tôi có thể làm cái này như thế nào?


Bạn có muốn một phiên SSH tương tác?
Không ai vào

@Nobody có tôi làm
Philip Kirkbride

Ok, đầu tiên tôi nghĩ rằng ý tưởng của tôi sẽ không hoạt động tương tác, nhưng một thử nghiệm ngắn cho thấy rằng nó không nên tôi đã viết một câu trả lời. :)
Không ai vào

Câu trả lời:


30

Một lựa chọn khác là sử dụng until.

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

Nếu bạn làm điều này nhiều lần cho một số máy chủ, hãy đặt nó vào một chức năng trong máy của bạn ~/.bashrc.

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

1
cảm ơn, tôi sẽ sử dụng tập lệnh lặp lại nhưng $thay vì lời nhắc :-)
Philip Kirkbride

14
Điều đáng chú ý là sshcó thể thoát với trạng thái khác không sau khi đã kết nối thành công nếu một cái gì đó bên ngoài kết nối kết thúc phiên, trong trường hợp đó tập lệnh sẽ cố gắng kết nối lại. Điều này có thể hoặc không thể là một tác dụng phụ mong muốn.
Austin Hemmelgarn

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

Việc !!lặp lại lệnh cuối cùng.


4
Sử dụng sáng tạo của lịch sử vỏ! +1
David Foerster

15

OpenSSH có một ConnectionAttemptscài đặt gần như những gì bạn muốn. Mặc định là 1 nhưng bạn có thể thay đổi nó trong ssh_confighoặc trên dòng lệnh:

ssh -o 'ConnectionAttempts 10' ...

Thật không may, bạn không thể điều chỉnh khoảng thời gian thử được cố định trong 1 giây, nhưng bạn có thể điều chỉnh thời gian chờ kết nối ConnectTimeout(tính bằng giây) theo cùng một cách.


Điều này dường như không hiệu quả với tôi: /
Freedo

@Freedo: Bạn có thể giải thích chính xác những gì bạn đã thử và chính xác những gì không hoạt động? Ngoài ra, có thể tốt hơn để viết một câu hỏi mới về vấn đề của bạn. Bạn có thể thu hút sự chú ý của tôi đến nó thông qua liên kết aa trong các bình luận.
David foerster

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

2
Hoặc, nếu bạn không thực sự muốn đăng nhập cho đến khi dịch vụ kết thúc , while ! nc -w5 -z host.example.com 22; do [...].
DopeGhoti

4

autosshgiữ phiên ssh sống. Với các tham số phù hợp, bạn cũng có thể khởi chạy nó khi hiện không thể kết nối và nó sẽ thử cho đến khi thành công. Điều này hoạt động tốt, nhưng nếu bạn muốn phần kết nối lại hoạt động tốt với các phiên tương tác, bạn sẽ cần kết hợp nó với screenhoặc tương đương.

Tôi khuyên bạn nên điều này:

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

Nhưng xem trang người đàn ông của nó để biết chi tiết. Với các tham số trên, autosshsẽ thử khởi chạy ssh mỗi AUTOSSH_POLLgiây, AUTOSSH_GATETIME=0làm cho nó thử lại nếu lần thử đầu tiên thất bại (vì vậy chắc chắn là những gì bạn muốn), -M 0vô hiệu hóa kiểm tra kết nối bằng autossh, tất cả các tùy chọn sau được chuyển sang ssh. Hai -otùy chọn thực hiện thoát ssh nếu các kết nối giảm hơn 5 giây.


2

Có nguy cơ chỉ cần ném mã vào một câu trả lời, kịch bản này hoạt động cho tôi hàng ngày. Tôi gọi nó resshvà nó có thể được sử dụng đơn giản như ressh {hostname}, hoặc cẩn thận,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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.