You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

远程主机重启后,如何检测并重新建立SSH连接?

检测远程主机重启完成的两种可行方案

一、改进版SSH连通性检测(优化基础方法)

单纯循环尝试SSH连接直到成功的方法确实比较粗糙,容易遇到假阳性:比如SSH服务已经启动,但系统的关键服务(或者你依赖的配置组件)还没完成初始化,这时候执行后续脚本大概率会失败。可以优化检测逻辑,结合系统启动时间或关键服务状态来判断:

示例脚本:

#!/bin/bash
# 记录重启前的远程主机启动时间(执行first-step.sh前获取)
PRE_REBOOT_UPTIME=$(ssh <host> 'cat /proc/uptime | cut -d" " -f1')

ssh <host> 'sh -s' < first-step.sh

rebooted=false
while [[ "$rebooted" = false ]]; do
    # 尝试SSH连接并获取当前启动时间,超时5秒避免等待过久
    CURRENT_UPTIME=$(ssh -o ConnectTimeout=5 <host> 'cat /proc/uptime | cut -d" " -f1' 2>/dev/null)
    # 对比启动时间:如果当前启动时间远小于重启前的,说明系统已重启
    if [[ -n "$CURRENT_UPTIME" && $(echo "$CURRENT_UPTIME < $PRE_REBOOT_UPTIME - 30" | bc) -eq 1 ]]; then
        # 可选:额外检查你依赖的关键服务是否就绪(比如nginx、docker)
        ssh <host> 'systemctl is-active --quiet nginx'
        if [[ $? -eq 0 ]]; then
            rebooted=true
        fi
    fi
    sleep 10
done

ssh <host> 'sh -s' < second-step.sh

二、远程主机主动通知本地(实现主动触发)

如果想让远程主机重启完成后主动发送信号触发后续流程,有两种实用方案:

1. 本地监听端口,远程发送连接信号

适用场景:内网环境(无需担心端口暴露风险),操作简单
实现步骤:

  • 本地先启动一个简单的端口监听进程,等待远程主机的连接信号
  • 在first-step.sh中添加重启后执行的脚本,让远程主机重启完成后主动连接本地端口

示例脚本:

#!/bin/bash
# 本地启动端口监听(自定义端口如12345),收到连接后自动退出
nc -l 12345 >/dev/null 2>&1 &
LISTEN_PID=$!

# 远程执行配置修改+添加重启后通知脚本
ssh <host> "sh -s" <<EOF
# 这里是first-step.sh的原有配置修改逻辑
# ...

# 添加重启后触发的通知命令到开机自启
echo 'nc <本地IP> 12345 -e echo "rebooted"' >> /etc/rc.local
chmod +x /etc/rc.local
# 执行重启
reboot
EOF

# 等待监听进程退出(即收到远程的重启完成信号)
wait $LISTEN_PID
# 清理远程主机的自启条目(可选)
ssh <host> 'sed -i "/nc <本地IP> 12345/d" /etc/rc.local'

ssh <host> 'sh -s' < second-step.sh

注意:需要确保远程主机安装netcat,本地防火墙允许对应端口的入站连接。

2. 利用SSH反向隧道实现安全通知

适用场景:公网或高安全性要求的环境
优势:无需额外开放端口,依赖SSH密钥登录(提前配置免密即可),安全性更高

示例脚本:

#!/bin/bash
# 远程执行配置修改+添加重启后通知脚本
ssh <host> "sh -s" <<EOF
# 这里是first-step.sh的原有配置修改逻辑
# ...

# 添加重启后触发的反向SSH通知命令到开机自启
echo 'ssh <本地用户>@<本地IP> "touch /tmp/remote_rebooted"' >> /etc/rc.local
chmod +x /etc/rc.local
# 执行重启
reboot
EOF

# 本地等待标记文件出现,确认远程已重启
rebooted=false
while [[ "$rebooted" = false ]]; do
    if [[ -f /tmp/remote_rebooted ]]; then
        rebooted=true
        rm /tmp/remote_rebooted
    fi
    sleep 5
done

ssh <host> 'sh -s' < second-step.sh
# 清理远程主机的自启条目(可选)
ssh <host> 'sed -i "/ssh <本地用户>@<本地IP>/d" /etc/rc.local'

内容的提问来源于stack exchange,提问作者dandan13

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 03:33:23