我正在努力理解 rsync 过滤系统,但它完全让我困惑。
我有以下“测试”目录结构来尝试理解它。没有过滤选项,以下是我的所有文件:
rsync -amv --dry-run /source /target
building file list ... done
source/
source/1.pdf
source/2.pdf
source/exclude_rules.txt
source/filter_rules.txt
source/excludedir/
source/excludedir/2.jpg
source/excludedir/4.pdf
source/subdir/
source/subdir/1.jpg
source/subdir/1.txt
source/subdir/3.pdf
source/subdir/subdir2/
source/subdir/subdir2/6.jpg
source/subdir/subdir2/6.pdf
我只想同步*.pdf
除某些目录之外的所有文件,即*exclude*
其中包含的任何目录。
我正在使用包含过滤规则的文件和以下命令:
rsync -amv --dry-run --filter='merge /filter_rules' /source /target
filter_rules 看起来像下面的变体,但我无法让它们产生我想要的结果:
-/ *exclude*/
+/ *.pdf
-/ *
我最接近的方法是简单排除:
-/ *exclude*/
得出的结果是:
building file list ... done
source/
source/1.pdf
source/2.pdf
source/exclude_rules.txt
source/filter_rules.txt
source/subdir/
source/subdir/1.jpg
source/subdir/1.txt
source/subdir/3.pdf
source/subdir/subdir2/
source/subdir/subdir2/6.jpg
source/subdir/subdir2/6.pdf
我如何过滤其余部分才能得到*.pdf
?
答案1
为了后代,我最终让它发挥作用,以下是我希望得到的说明:
rsync
使用完整文件列表启动过滤过程- 过滤规则是按顺序处理的(我花了一段时间才明白这一点)
- 您可能拥有所有正确的规则,但顺序不正确,因此如果您使用外部排除或包含文件,则可能需要使用过滤文件对它们重新排序,以便您可以混合和匹配包含/排除规则,或者在 cli 本身上列出
- 对于每个文件,第一个匹配的过滤规则将文件放入两个存储桶中的一个,包括或排除。
- 第一个匹配的规则之后的规则不被应用!
- 每条规则仅对那些“超过”先前规则的文件起作用,而这些规则不匹配
- 不匹配任何规则的文件将被包含在内
- 最后一条规则是最重要且最不直观的,它的意思是排除到那时为止未明确包括的所有内容。
因此,最终的工作结果如下:
-/ *exclude*/
+/ */
+/ *.pdf
-/ *
最初,我将这些规则放在单独的包含文件和排除文件中,但这不允许正确的顺序。
答案2
我仍然在 rsync 中使用 --exclude-from,但是当我尝试使过滤功能正常工作时,此链接非常有用。
https://stackoverflow.com/questions/35364075/using-rsync-filter-to-include-exclude-files
编辑 - OP 在自己的回答中提到了这一点,但根据要求...该链接中的有用信息
解释:
(最后只重新措辞了手册,但正如你所说,手册有点神秘)
每次必须通过 rsync 传输文件时,规则都会从上到下读取。但对于您而言,/mnt/data/i-want-to-rsyncthisdirectory/ 未备份,因为您排除了 /mnt,这会缩短您的包含规则。因此,解决方案是包含每个文件夹和子文件夹,直到您想要备份的文件夹,然后逐个子文件夹排除您不想备份的内容。
请注意每个子文件夹排除末尾的 *。它将阻止 rsync 备份位于这些子文件夹中的文件和文件夹,我认为这正是您想要的。更简单的解决方案:(编辑 2)
您甚至可以使用版本 >2.6.7 中添加的 *** 模式来简化此过程:
- /mnt/
- /mnt/数据/
- /mnt/data/我想要-rsync这个目录/***
- /mnt/**
该运算符允许您使用 ** 通配符进行排除,从而只有一条排除行。
我还发现,您可以通过以下 rsync 参数了解哪些过滤规则排除/包含每个文件或文件夹:
--详细 --详细
结合 --dry-run 参数,您应该能够调试您的问题 >:)