如何让Bash脚本等待远程SSH执行的rsync任务完成?
问题描述
我需要为我的Bash脚本寻求帮助,该脚本通过SSH连接到远程服务器,并执行包含多个rsync命令的脚本。当前脚本已完成日期和时间的前置检查(功能正常),内容如下:
logger -p local0.info -t dhcp-join-notify "NAS is reachable, start syncing" sleep 1 ssh admin@192.168.99.8 -p 2222 "bash -s" < /root/qnap-ssh.sh sleep 1 logger -p local0.info -t dhcp-join-notify "Send poweroff to server" sleep 1 ssh admin@192.168.99.8 -p 2222 'poweroff' sleep 1
远程执行的脚本/root/qnap-ssh.sh内容如下:
#!/bin/bash /share/HDA_DATA/.qpkg/Entware-ng/bin/rsync -Pvarzz rsync://192.168.99.6/qnap-public2/Digital-Fotos /share/HDA_DATA/Public && /share/HDA_DATA/.qpkg/Entware-ng/bin/rsync -Pvarzz rsync://192.168.99.6/qnap-public2/eBooks /share/HDA_DATA/Public && /share/HDA_DATA/.qpkg/Entware-ng/bin/rsync -Pvarzz rsync://192.168.99.6/docker-data /share/HDA_DATA/Public/docker-data
运行脚本时,通过syslog可见命令均已执行,但关键步骤ssh admin@192.168.99.8 -p 2222 "bash -s" < /root/qnap-ssh.sh仅1-2秒就结束了,我需要让脚本等待该步骤完全完成后再继续执行后续的关机命令。
解决方案
默认情况下,SSH命令会等待远程端的命令/脚本执行完成后才返回,所以当前SSH步骤快速结束,说明远程的qnap-ssh.sh脚本已经执行完毕(要么rsync真的瞬间完成,要么脚本中途出错退出)。可以通过以下步骤排查并解决问题:
1. 给远程脚本添加日志,排查rsync执行状态
修改/root/qnap-ssh.sh,添加详细日志输出,确认rsync是否真的在执行,或者是否有错误导致提前退出:
#!/bin/bash # 定义日志文件路径 LOG_FILE="/tmp/rsync_sync.log" # 清空旧日志(可选) > $LOG_FILE echo "[$(date '+%Y-%m-%d %H:%M:%S')] Starting rsync sync tasks" >> $LOG_FILE # 执行第一个rsync并记录输出 /share/HDA_DATA/.qpkg/Entware-ng/bin/rsync -Pvarzz rsync://192.168.99.6/qnap-public2/Digital-Fotos /share/HDA_DATA/Public >> $LOG_FILE 2>&1 if [ $? -ne 0 ]; then echo "[$(date '+%Y-%m-%d %H:%M:%S')] Digital-Fotos sync failed" >> $LOG_FILE exit 1 fi echo "[$(date '+%Y-%m-%d %H:%M:%S')] Digital-Fotos sync completed" >> $LOG_FILE # 执行第二个rsync并记录输出 /share/HDA_DATA/.qpkg/Entware-ng/bin/rsync -Pvarzz rsync://192.168.99.6/qnap-public2/eBooks /share/HDA_DATA/Public >> $LOG_FILE 2>&1 if [ $? -ne 0 ]; then echo "[$(date '+%Y-%m-%d %H:%M:%S')] eBooks sync failed" >> $LOG_FILE exit 1 fi echo "[$(date '+%Y-%m-%d %H:%M:%S')] eBooks sync completed" >> $LOG_FILE # 执行第三个rsync并记录输出 /share/HDA_DATA/.qpkg/Entware-ng/bin/rsync -Pvarzz rsync://192.168.99.6/docker-data /share/HDA_DATA/Public/docker-data >> $LOG_FILE 2>&1 if [ $? -ne 0 ]; then echo "[$(date '+%Y-%m-%d %H:%M:%S')] docker-data sync failed" >> $LOG_FILE exit 1 fi echo "[$(date '+%Y-%m-%d %H:%M:%S')] All sync tasks completed successfully" >> $LOG_FILE
执行脚本后,登录远程服务器查看/tmp/rsync_sync.log,就能清楚知道每个rsync任务的执行状态。
2. 在本地脚本中捕获远程脚本的退出码
修改本地的SSH命令,捕获远程脚本的退出状态,确保只有同步成功才继续执行关机命令:
logger -p local0.info -t dhcp-join-notify "NAS is reachable, start syncing" # 添加ServerAliveInterval防止SSH连接因长时间无输出断开,移除无意义的sleep ssh -o ServerAliveInterval=30 -p 2222 admin@192.168.99.8 "bash -s" < /root/qnap-ssh.sh SYNC_EXIT_CODE=$? if [ $SYNC_EXIT_CODE -eq 0 ]; then logger -p local0.info -t dhcp-join-notify "Sync completed successfully, sending poweroff command" ssh -p 2222 admin@192.168.99.8 'poweroff' else logger -p local0.error -t dhcp-join-notify "Sync failed with exit code $SYNC_EXIT_CODE, aborting poweroff" exit 1 fi
3. 检查rsync服务与权限
确认以下几点:
- 远程服务器上的rsync客户端路径
/share/HDA_DATA/.qpkg/Entware-ng/bin/rsync正确无误 - rsync服务器(192.168.99.6)正常运行,远程服务器能访问该服务器的rsync服务端口(默认873)
- 远程服务器的
admin用户对目标目录/share/HDA_DATA/Public及其子目录有写入权限 - rsync服务器端对共享目录
qnap-public2、docker-data有读取权限
内容的提问来源于stack exchange,提问作者Dominik82
相关产品推荐
相关产品推荐

