通过SSH执行远程服务器shell脚本时连接挂起如何解决?
问题根因
SSH 会话需要等待远程侧所有关联进程关闭 stdin、stdout、stderr 三个标准流后才会主动断开。后台启动的脚本仍然持有这三个流的句柄,因此SSH连接会一直挂起,哪怕脚本已经进入后台运行。另外SSH会话断开时默认会向会话内所有进程发送SIGHUP信号,还有可能导致后台运行的脚本被强制终止。
解决方案
使用如下命令即可解决挂起问题,同时保证脚本后台稳定运行:
ssh -o StrictHostKeyChecking=no 10.0.0.1 'nohup ~/data/data-csv.sh > ~/data/$(hostname).csv 2>&1 < /dev/null & echo $! > ~/data/pid.log'
参数说明
nohup:让目标脚本忽略SIGHUP信号,避免SSH断开时脚本被系统终止2>&1:将标准错误流重定向到标准输出,也可以根据需要单独重定向到错误日志文件,例如2> ~/data/run-error.log< /dev/null:将标准输入重定向到空设备,彻底释放所有标准流的句柄,SSH检测到所有流都关闭后就会正常退出- 推荐将原写法中的
`hostname`替换为$(hostname),是兼容性更强的POSIX标准写法,避免嵌套引号时出现解析错误
备选方案(不使用nohup)
如果服务器环境不支持nohup,也可以用setsid让进程直接脱离当前SSH会话组,效果一致:
ssh -o StrictHostKeyChecking=no 10.0.0.1 'setsid ~/data/data-csv.sh > ~/data/$(hostname).csv 2>&1 < /dev/null & echo $! > ~/data/pid.log'
内容的提问来源于stack exchange,提问作者A D
相关产品推荐
相关产品推荐

