用 rsync 同步 meta 目录,我漏掉了隐藏的校验文件

上周在测试机上跑一次 meta 配置同步,源目录 1.2GB、约 3.4 万个文件,其中大部分是历史快照。目标机是另一台内网机器,平时靠一条 rsync 命令推过去。现象很简单:同步完跑校验脚本,有 7 个 meta 文件报字段缺失,但源端读出来是全的。

我先怀疑是传输中断,重跑一遍,还是同样 7 个文件。把文件单独 scp 过去,校验通过。说明不是内容问题,是 rsync 压根没传这几个文件。用 rsync -av --dry-run 看列表,才发现它们根本没出现在待传队列里。

原因是这几个文件在源端是 .meta.<name>.snapshot 这种隐藏命名,而我的命令里带了 --exclude='.*',本意是排除 .git 和编辑器临时文件。改成显式排除:

rsync -av \
  --exclude='.git/' \
  --exclude='*.swp' \
  --exclude='.DS_Store' \
  src/meta/ dest:/data/meta/

再跑 dry-run,7 个文件出现在列表里,正式同步后校验全绿。

为什么这样改:--exclude 的匹配是按路径模式来的,.* 会命中任何以点开头的路径段,包括我本来想保留的隐藏文件。代价是排除规则变长了,以后新增临时文件类型得手动补。另一种做法是把隐藏文件改成不带点的前缀,但那要动上游生成逻辑,暂时不值得。

会失效的地方也踩过:一是目标端如果已有同名旧文件,rsync 默认按大小和 mtime 判断,隐藏文件被排除时旧版本会一直留着,看起来像“同步成功但内容旧”;二是用 --delete 时,排除规则里的文件不会被删除,得确认这是你要的行为;三是我在一台 macOS 上跑,.DS_Store 排除写在前面才生效,顺序有影响。

现在我的习惯是每次改排除规则先跑 --dry-run 数一遍文件数,和源端 find src/meta -type f | wc -l 对一下,差多少心里有数。

你们同步 meta 目录时,隐藏文件是显式列入白名单,还是干脆改命名规则绕开这个坑?

0
赞同度 100% · 0 条评论 · 5 阅读

0 条评论

支持 Markdown · 回复会实时推送给对方

还没有评论,写下第一条。