如何成功运行ssh命令?


28

有时我会重启设备,并且需要ssh在准备就绪时重新启动。

我想每5秒运行ssh命令,直到命令成功。

我的第一次尝试:

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

我怎样才能做到这一点?


您是否需要交互式SSH会话?
没人

@Nobody是我做的
菲利普Kirkbride

好的,我最初以为我的想法无法交互工作,但是经过简短的测试表明它确实可行,所以我还是写了一个答案。:)
没人

Answers:


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如果连接外部的某些东西终止了会话,则在成功连接后可以退出并返回非零状态,在这种情况下,脚本将尝试重新连接。这可能是或可能不是理想的副作用。
奥斯汀·海默尔加恩

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

!!重复最后命令。


4
创造性地使用shell历史记录!+1
David Foerster's

15

OpenSSH的ConnectionAttempts设置几乎可以满足您的要求。默认值为1,但您可以ssh_config在命令行中或在命令行中进行更改:

ssh -o 'ConnectionAttempts 10' ...

不幸的是,您无法调整固定为1秒的尝试间隔,但是可以ConnectTimeout以相同的方式调整连接尝试超时(以秒为单位)。


这似乎对我不起作用:/
Freedo

@Freedo:您能解释一下您到底尝试了什么,而哪些没用呢?另外,最好写一个关于您的问题的新问题。欢迎您通过评论中的链接吸引我的注意。
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

但是请参阅其手册页以获取详细信息。使用以上参数,autossh将每秒钟尝试启动ssh AUTOSSH_POLLAUTOSSH_GATETIME=0如果第一次尝试失败(肯定是您想要的),-M 0将使其重试,禁用autossh的连接检查,所有以后的选项都传递给ssh。-o如果连接断开超过5s,则这两个选项会使ssh退出。


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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.