SSH执行长耗时远程脚本完成后本地bash脚本无法继续执行怎么办
问题根因
远程脚本完整执行完成,但本地ssh命令始终不返回、后续本地操作无法执行的情况,核心是SSH会话退出阻塞,和连接中断、脚本被中途终止没有关联。
具体触发逻辑:
- SSH会话只有在绑定的标准输入、标准输出、标准错误三个文件描述符全部释放后,才会关闭连接、将执行控制权交还给本地shell
- 哪怕远程脚本的所有逻辑都执行完毕,只要有任意一个从当前SSH会话派生的进程持有这三个标准流的句柄,SSH就会持续等待句柄释放,不会主动返回退出码,直接卡在本地脚本的执行流上
- 5分钟的短测试脚本执行周期短,既没有触发中间网络设备的空闲连接回收,也没有残留进程占住标准流句柄,因此可以跑通全流程
解决方法
- 最适配需求的写法:在本地ssh调用时,对远程命令的标准流做安全重定向,切断无关进程和SSH通道的绑定,避免被残留句柄阻塞。示例写法:
这种写法既可以完整留存远程脚本的执行日志方便排查,又能保证SSH在远程脚本主流程跑完后立刻返回。如果不需要留存日志,可将输出路径替换为#!/bin/bash # 执行前置操作 ssh remote@remote "/home/remote/path/to/script.sh </dev/null >/tmp/remote_run.log 2>&1" echo "Done" # 执行后续操作/dev/null - 增加SSH保活参数,适配15分钟级的长连接执行场景:在ssh命令中加入保活配置,每30秒发送一次连接探测包,避免中间网络设备因判定连接空闲超时回收通道,导致会话异常卡住:
ssh -o ServerAliveInterval=30 remote@remote "/home/remote/path/to/script.sh </dev/null >/tmp/remote_run.log 2>&1" - 注意:不要使用
screen/nohup的脱离会话用法,这种方式会让远程进程彻底和SSH会话解绑,本地ssh命令会在下发完命令后立刻返回,根本等不到远程脚本执行完成,和“必须等远程脚本跑完再执行本地后续操作”的需求完全冲突
另外补充:提供的测试脚本中echo "Start..." &的后台输出写法,会让该echo进程继承SSH会话的标准输出,虽然进程本身执行很快,但碰到SSH输出缓冲区滞留的情况,也会触发会话等待,进一步加剧SSH不返回的问题。
内容的提问来源于stack exchange,提问作者Fritzip
相关产品推荐
相关产品推荐

