使用Rsync过滤器包含/排除文件

use*_*823 6 linux bash rsync

我正在尝试备份文件系统,排除/mnt但在其中包括特定路径/mnt,似乎建议在--include和--exclude上使用--filter,但是我似乎无法使它完成我的工作出价,例如:

rsync -aA -H --numeric-ids -v --progress --delete \
  --filter="merge /tmp/mergefilter.txt" /  /mnt/data/mybackup/
Run Code Online (Sandbox Code Playgroud)

我的/tmp/mergefilter.txt说:

+ /mnt/data/i-want-to-rsyncthisdirectory/
- /dev
- /sys/
- /tmp/
- /run/
- /mnt/
- /proc/
- /media/
- /var/swap
- /lost+found/
Run Code Online (Sandbox Code Playgroud)

以“-”开头的所有路径都将被忽略,但是我的include for /mnt/data/i-want-to-rsyncthisdirectory/似乎永远不会得到rsync'd。顺序和/或包括/排除尾部斜杠似乎并未改变与我要包括的路径有关的行为。

编辑:请注意,我确实要按照指定为/的源来备份/ etc / usr / var等。

赞赏任何指导,因为手册页有点雷区。

Mar*_*cus 7

对我来说,此命令正在完成此工作:

rsync -aA -H --numeric-ids -v --progress --delete \
--filter="+ /mnt/data/i-want-to-rsyncthisdirectory/" \
--filter="- *" . /mnt/data/mybackup/
Run Code Online (Sandbox Code Playgroud)

基本上,我对有问题的目录使用了+过滤器,并排除了所有其他目录(如您在给定示例中所做的那样)。

无需显式否定所有您不想同步的目录。相反,您可以忽略除所讨论问题以外的所有内容。


小智 7

这个问题已经很老了,但我认为这可能对您有帮助:

(摘自rsync 3.1.2手册)

请注意,当使用--recursive(-r)选项(由-a表示)时,每个路径的每个子组件都是从上至下访问的,因此包含/排除模式将递归应用于每个子组件的全名(例如要包含“ / foo / bar / baz”,则不能排除子组件“ / foo”和“ / foo / bar”)。当rsync找到要发送的文件时,排除模式实际上会使目录遍历阶段短路。如果模式排除了特定的父目录,则它会导致更深的包含模式无效,因为rsync不会通过层次结构的该排除部分下降。使用尾随“ *”规则时,这一点尤其重要。例如,这将不起作用:

         + /some/path/this-file-will-not-be-found
         + /file-is-included
         - *
Run Code Online (Sandbox Code Playgroud)

失败是因为“ *”规则排除了父目录“ some”,因此rsync永远不会访问“ some”或“ some / path”目录中的任何文件。一种解决方案是使用一条规则要求将层次结构中的所有目录包括在内:“ + * /”(将其放在“-*”规则之前的某个位置),并可能使用--prune-empty-dirs选项。另一个解决方案是为所有需要访问的父目录添加特定的包含规则。例如,这套规则很好用:

         + /some/
         + /some/path/
         + /some/path/this-file-is-found
         + /file-also-included
         - *
Run Code Online (Sandbox Code Playgroud)

我在原始答案中提出了实际上不起作用的内容(我对其进行了测试)。我复制了一棵与您相似的树,该解决方案现在应该可以使用:

+ /mnt/
+ /mnt/data/
+ /mnt/data/i-want-to-rsyncthisdirectory/
- /mnt/data/*
- /mnt/*
- /dev
- /sys/
- /tmp/
- /run/
- /proc/
- /media/
- /var/swap
- /lost+found/
Run Code Online (Sandbox Code Playgroud)

说明:

(仅在最后改写了手册,但正如您所说的,手册有点含糊)

每次必须通过rsync传输文件时,都会从上至下读取规则。但在您的情况下,/ mnt / data / i-want-to-rsyncthisdirectory /不会备份,因为您排除了/ mnt,这会使您的包含规则短路。因此,解决方案是包括每个文件夹和子文件夹,直到要备份的文件夹为止,然后逐个子文件夹排除您不想备份的子文件夹。

请注意每个子文件夹排除项末尾的*。这将阻止rsync备份位于这些子文件夹中的文件和文件夹,这是您想要的。

更简单的解决方案:(编辑2)

您甚至可以使用版本2.6.7中添加的***模式来简化此操作:

+ /mnt/
+ /mnt/data/
+ /mnt/data/i-want-to-rsyncthisdirectory/***
- /mnt/**
Run Code Online (Sandbox Code Playgroud)

此运算符允许您使用**通配符进行排除,因此只有一个排除行。

我还发现,由于以下rsync参数,您可以了解哪些过滤器规则排除/包括了每个文件或文件夹:

--verbose --verbose
Run Code Online (Sandbox Code Playgroud)

结合--dry-run参数,您应该可以调试问题了:)

  • +1为您澄清过滤模式。是否花了几个小时想知道为什么仅在我的尝试中包含子文件夹2时文件夹/子文件夹1/子文件夹2被忽略..非常有帮助 - 谢谢! (2认同)