如何使用rsync从同子目录包含指定少量目录并排除其余内容?
Rsync 精准包含指定version目录、排除其他版本的正确姿势
嗨,这个问题我太熟了!rsync的include/exclude规则很容易踩顺序的坑,尤其是当你需要包含的目录远少于排除的内容时,得把规则的优先级和顺序搞对才行,不然怎么调都不生效。
核心逻辑先搞懂
rsync的过滤规则是从上到下依次匹配,一旦某个文件/目录匹配到了某条规则,就会停止后续的规则判断。所以关键是:
- 必须先确保父目录不会被排除,否则子目录再怎么写include规则都没用(rsync会直接跳过整个父目录,根本不会遍历到子目录)
- 把需要优先保留的规则放在前面,最后再写排除所有其他内容的兜底规则
针对你的需求的具体命令
假设你的源目录是/src/,要同步到/dest/,需要包含version1、version2,排除version3和其他所有未指定的目录,命令应该这么写:
rsync -av --include='*/' --include='version1/***' --include='version2/***' --exclude='*' /src/ /dest/
逐个参数解释(敲黑板)
-av:归档模式(保留权限、时间戳等)+ 显示详细同步信息,是rsync日常使用的标配组合--include='*/':先include所有子目录,这一步非常重要!rsync默认会跳过未被include的目录,所以必须先让它能遍历到所有子目录,后面的versionX规则才会生效--include='version1/***':精准匹配version1目录下的所有文件和子目录,***表示递归匹配该目录下的所有层级内容--include='version2/***':和上面同理,专门保留version2的所有内容--exclude='*':最后写兜底规则,排除所有没被前面include规则匹配到的内容(自然就包含了version3)
实用测试技巧
怕写错命令误删或者漏同步?可以加-n(也就是--dry-run)参数做模拟运行,看看哪些文件会被同步,确认没问题再去掉-n执行真实同步:
rsync -avn --include='*/' --include='version1/***' --include='version2/***' --exclude='*' /src/ /dest/
特殊场景调整
如果你的versionX目录是在某个特定父目录下(比如/src/releases/versionX),那要调整include的路径,确保父目录被包含:
rsync -av --include='releases/' --include='releases/version1/***' --include='releases/version2/***' --exclude='*' /src/ /dest/
另外注意源目录末尾的/:如果源目录写/src(不带/),rsync会把src目录本身复制到目标;如果是/src/,则复制src下的内容到目标,别搞混了!
内容的提问来源于stack exchange,提问作者VinPro




