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

如何让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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 13:05:21