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

Rsync使用--compare-dest参数时通配符无法识别的问题求助

Rsync使用--compare-dest参数时通配符无法识别的问题求助

我完全理解你想用rsync实现多层增量备份的需求,遇到通配符在--compare-dest里不生效的问题确实挺闹心的!咱们来一步步拆解问题,再给出可行的解决办法:

为什么通配符在这里不工作?

首先得搞清楚:shell的通配符(比如*)是在rsync执行前由shell展开的,但--compare-dest参数一次只能接受单个路径。这就会出现两种情况:

  1. 当目标目录下还没有任何子备份目录时,shell无法展开*,会直接把它当成字面量传给rsync,导致rsync找不到/home/j/test/destination/*这个路径,也就是你第一次遇到的报错。
  2. 当目标目录下已有子目录(比如00/),shell会把*展开成这个唯一的路径,但rsync只会对比这一个目录——如果你的预期是对比所有历史备份目录,那显然达不到效果,甚至如果这个目录和源目录差异很大,就会出现全量复制的情况。

更关键的是:rsync本身支持多个--compare-dest参数,它会依次对比这些路径,找到已存在的文件来实现增量备份,但直接用通配符没法自动生成多个--compare-dest参数。

解决办法:用shell脚本批量生成多个--compare-dest参数

我们可以通过shell循环,把所有历史备份目录逐个作为--compare-dest的参数传递给rsync,完美实现多层对比的需求。

比如用bash写一个简单的脚本:

# 定义源目录、目标根目录和新备份目录
SOURCE="/home/j/test/source/"
DEST_ROOT="/home/j/test/destination/"
NEW_DEST="${DEST_ROOT}01/"  # 这里可以换成动态命名,比如按时间戳:$(date +%Y%m%d%H%M)

# 收集所有历史备份目录,按从新到旧排序(提高对比效率)
BACKUP_DIRS=($(ls -td "${DEST_ROOT}"*/))

# 构建rsync的参数列表
RSYNC_ARGS=(-av "${SOURCE}")
for dir in "${BACKUP_DIRS[@]}"; do
    RSYNC_ARGS+=(--compare-dest="$dir")
done
RSYNC_ARGS+=("${NEW_DEST}")

# 执行rsync
"${RSYNC_ARGS[@]}"

几个关键细节提醒

  • 排序逻辑:用ls -td可以让最新的备份目录排在前面,rsync会优先对比最近的备份,能更快找到已存在的文件,提升备份效率。
  • 空格兼容:用数组RSYNC_ARGS来存储参数,避免目录名带空格时出现解析错误。
  • 动态命名新目录:如果不想手动指定01/、02/,可以用时间戳生成目录名,比如NEW_DEST="${DEST_ROOT}$(date +%Y%m%d%H%M)/",这样每次备份都是唯一的目录,更规范。

这样操作后,rsync就会对比所有历史备份目录,只复制源目录中新增或修改的文件,真正实现多层增量备份啦!

备注:内容来源于stack exchange,提问作者Jam

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.17 10:25:29