You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

禁用rsync时,每分钟轮询远程服务器复制修改文件方案咨询

无rsync时的远程文件增量同步方案

你的需求很明确:没法用rsync工具,只能通过每分钟轮询SFTP服务器,同步自上次检查后更新的文件。先梳理下你现有代码里的小问题,再给你优化后的完整实现方案。

现有代码的待完善点

  • 变量名拼写错误:mododTime应该是modTime
  • 逻辑不完整:lastModT变量缺少初始化和后续更新逻辑
  • 效率问题:每次都完整下载文件到临时目录,哪怕文件没修改,浪费带宽
  • 错误处理缺失:没考虑远程文件不存在、scp下载失败等异常场景

优化后的完整实现

我们可以先远程获取文件的修改时间,判断是否比上次同步的时间更新,再决定是否下载,这样能避免无意义的文件传输。同时完善错误处理和日志记录:

#!/bin/bash

# 配置参数(根据你的实际环境修改)
SFTP_USER="your_sftp_user"
SFTP_SERVER="your_sftp_server_ip"
SFTP_PATH="/remote/file/directory"
FILE_NAME="your_target_file.txt"
PUT_TEMP_SFTP_PATH="/local/temp/folder"
TARGET_PATH="/local/target/folder"
POLL_INTERVAL=60  # 轮询间隔(秒)

# 初始化上次同步时间(设置为极早时间,确保第一次会同步)
lastModTime=0
# 可选:如果需要脚本重启后保留上次同步状态,可将时间写入文件
LAST_MOD_RECORD="/var/tmp/sync_last_mod.txt"
if [ -f "${LAST_MOD_RECORD}" ]; then
    lastModTime=$(cat "${LAST_MOD_RECORD}")
fi

# 创建必要目录(不存在则自动创建)
mkdir -p "${PUT_TEMP_SFTP_PATH}" "${TARGET_PATH}"

echo "Starting file sync poller. Checking every ${POLL_INTERVAL} seconds..."

while true; do
    # 远程获取文件的Unix时间戳(通过sftp执行远程命令)
    remoteModTime=$(sftp -q "${SFTP_USER}@${SFTP_SERVER}" <<EOF
cd ${SFTP_PATH}
!date +%s -r ${FILE_NAME}
EOF
    2>/dev/null)

    # 检查远程获取是否成功(比如文件不存在、权限不足)
    if [ -z "${remoteModTime}" ]; then
        echo "$(date '+%Y-%m-%d %H:%M:%S'): Warning - Remote file ${FILE_NAME} not found or access denied"
        sleep ${POLL_INTERVAL}
        continue
    fi

    # 判断文件是否有更新
    if [ "${remoteModTime}" -gt "${lastModTime}" ]; then
        echo "$(date '+%Y-%m-%d %H:%M:%S'): Detected file change, starting download..."
        # 下载文件到临时目录,保留原属性(权限、修改时间)
        if scp -pq "${SFTP_USER}@${SFTP_SERVER}:${SFTP_PATH}/${FILE_NAME}" "${PUT_TEMP_SFTP_PATH}/"; then
            # 复制到目标目录,同样保留属性
            cp -p "${PUT_TEMP_SFTP_PATH}/${FILE_NAME}" "${TARGET_PATH}/"
            # 更新上次同步时间
            lastModTime="${remoteModTime}"
            # 可选:将时间写入文件持久化
            echo "${remoteModTime}" > "${LAST_MOD_RECORD}"
            echo "$(date '+%Y-%m-%d %H:%M:%S'): File synced successfully to ${TARGET_PATH}"
        else
            echo "$(date '+%Y-%m-%d %H:%M:%S'): Error - Failed to download file from SFTP server"
        fi
    else
        echo "$(date '+%Y-%m-%d %H:%M:%S'): No changes detected"
    fi

    # 等待下一轮轮询
    sleep ${POLL_INTERVAL}
done

关键优化说明

  • 先查时间再下载:通过sftp执行远程date命令获取文件时间戳,避免无意义的文件传输,节省带宽
  • 完善错误处理:覆盖远程文件不存在、下载失败等场景,输出清晰的时间戳日志
  • 属性保留scp -pqcp -p确保文件的修改时间、权限等属性同步到本地
  • 状态持久化(可选):通过本地文件记录上次同步时间,脚本重启后无需重新同步历史文件
  • 目录自动创建:提前创建临时目录和目标目录,避免因目录不存在导致的执行失败

使用注意事项

  1. 确保本地与远程服务器的系统时间同步,否则时间戳比较会出错
  2. 给脚本添加可执行权限:chmod +x sync_script.sh
  3. 可通过nohup ./sync_script.sh &让脚本后台运行,或用systemd配置成服务实现开机自启

内容的提问来源于stack exchange,提问作者Pratik Kumar

火山引擎 最新活动