以userB身份SSH执行命令的Bash脚本故障排查求助
修复你的SSH自动重试脚本问题
嘿,我来帮你拆解这两个脚本问题,一步步给你修复方案:
问题1:服务器宕机时无输出,恢复后循环无法退出
- 你原来的
until ssh userB@IP; do...逻辑里,ssh userB@IP默认会启动交互式会话。当服务器恢复后,SSH连接成功但会一直停在交互式界面,不会返回退出码,导致until循环永远无法结束。 - 服务器宕机时,SSH的错误提示(比如连接超时、拒绝)是输出到stderr的,而脚本默认只显示stdout内容,所以你看不到任何重试提示。
问题2:服务器正常时SSH会话无法退出
- 你用了
ssh -tT组合参数,这俩是冲突的:-t是强制分配伪终端,-T是禁止分配伪终端,同时使用会导致终端处理异常,进而让会话无法正常退出。 - 脚本里连续执行了两次SSH操作:第一次是
until里的交互式连接,第二次是单独的命令执行,第一次的交互式会话会一直挂着,除非你手动退出,这完全是冗余且错误的逻辑。
修复后的完整脚本
#!/bin/bash # 配置远程连接信息 REMOTE_USER="userB" REMOTE_IP="你的目标主机IP" RETRY_INTERVAL=5 # 重试间隔(秒) # 循环重试直到SSH连通成功 until ssh -q "$REMOTE_USER@$REMOTE_IP" true 2>&1; do echo "$(date '+%Y-%m-%d %H:%M:%S'): 服务器不可达,${RETRY_INTERVAL}秒后重试..." sleep $RETRY_INTERVAL done # 连通后执行目标命令 echo "$(date '+%Y-%m-%d %H:%M:%S'): 服务器连接成功,开始执行命令..." ssh "$REMOTE_USER@$REMOTE_IP" << EOF echo 'test' > test # 在这里添加更多需要执行的命令,比如: # mkdir -p new_dir # cp file.txt new_dir/ EOF echo "$(date '+%Y-%m-%d %H:%M:%S'): 所有命令执行完成,SSH会话已自动退出"
关键修复点说明
- 用
ssh -q ... true替代交互式SSH:-q开启安静模式,减少不必要的输出;true是一个无操作的成功命令,SSH执行完就会返回退出码0,不会进入交互式会话,这样until循环能正常判断连接状态。
2>&1重定向错误输出:把SSH的错误信息(比如连接失败提示)重定向到标准输出,让你能看到重试过程的反馈。- 添加重试间隔:避免短时间内频繁发起连接请求,减轻服务器和网络压力。
- 移除冲突的
-tT参数:直接用普通SSH加here-doc执行命令,SSH会在执行完所有命令后自动退出会话。 - 合并SSH操作:在确认连接成功后,直接执行目标命令,不需要重复建立连接,逻辑更简洁高效。
内容的提问来源于stack exchange,提问作者jar31
相关产品推荐
相关产品推荐

