rsync仅包含指定目录失效:测试正常但备份至外部盘异常
问题描述
我用rsync写了一个增量备份脚本,通过include文件设置只备份主目录下Library里的Application Support和Preferences子目录,排除Downloads和Library的其他内容。这个配置在测试目录里运行正常,但备份到外部驱动器/Volumes/Stuff/Backup/时,本该被排除的内容总是被包含进来,达不到预期效果,请问问题出在哪?
脚本代码
SOURCE_DIR="$HOME/" DEST_DIR="/Volumes/Stuff/Backup/" if [ ! -d "$SOURCE_DIR" ]; then echo "\"${SOURCE_DIR}\" does not exist."; exit elif [ ! -d "$DEST_DIR" ]; then echo "\"${DEST_DIR}\" does not exist."; exit fi PARENT_DIR="$(cd "$(dirname "$0")"; pwd)" DIR_NAME="$(date '+%Y%m%dT%H%M%S')" BACKUP_DIR="$DEST_DIR/$DIR_NAME" LATEST_LINK="$DEST_DIR/latest" INCLUDE_FILE="$PARENT_DIR/include.txt" mkdir -p "$BACKUP_DIR" rsync -av \ --delete \ --prune-empty-dirs \ --include-from="$INCLUDE_FILE" \ --link-dest="$LATEST_LINK" \ "$SOURCE_DIR" \ "$BACKUP_DIR" rm -f "$LATEST_LINK" ln -s "$BACKUP_DIR" "$LATEST_LINK" echo "Size of current backup:" "$(du -sh "$BACKUP_DIR")" echo "Size of all backups:" "$(du -sh "$DEST_DIR")"
include.txt内容
- .DS_Store - /Downloads/ + /Library/ + /Library/Application Support/*** + /Library/Preferences/*** - /Library/***
问题分析与解决方案
1. 通配符使用错误
你在include.txt里用了***作为递归通配符,但rsync仅支持**来匹配目录下所有层级的内容,***是无效写法,这会导致Application Support和Preferences下的子文件/目录无法被正确匹配包含,进而让后续的排除规则失效。
2. 缺少全局排除规则
rsync默认会包含所有未被明确排除的内容,你的规则里没有最后兜底的- *,所以主目录下除了Downloads和你指定的几个Library子目录外,其他所有内容都会被同步——测试目录内容少没暴露这个问题,但主目录内容多就会显现异常。
3. 跨文件系统硬链接的潜在影响
如果外部磁盘的文件系统不支持硬链接(比如FAT32),--link-dest会直接失效,rsync会改为复制文件。另外,如果之前的latest备份本身包含了不该有的内容,增量备份会通过硬链接保留这些内容,看起来像是规则没生效。
修正后的include.txt
把通配符改成**,并添加全局排除规则:
- .DS_Store - /Downloads/** + /Library/ + /Library/Application Support/** + /Library/Preferences/** - /Library/** - *
调试与验证步骤
- 先运行带
-n(模拟运行)的rsync命令,查看实际要同步的内容,确认规则是否生效:
rsync -avn \ --delete \ --prune-empty-dirs \ --include-from="$INCLUDE_FILE" \ --link-dest="$LATEST_LINK" \ "$SOURCE_DIR" \ "$BACKUP_DIR"
- 如果外部磁盘是FAT32等不支持硬链接的文件系统,要么更换为APFS/HFS+这类支持硬链接的文件系统,要么去掉
--link-dest(但会失去增量备份的硬链接优势)。 - 第一次备份时可以暂时去掉
--link-dest,先做一次符合规则的全量备份,之后再恢复增量备份的配置。
内容的提问来源于stack exchange,提问作者fruitsalad
相关产品推荐
相关产品推荐

