用 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 条评论
还没有评论,写下第一条。