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

时间:2016-02-12 13:40:13

标签: linux bash rsync

我尝试备份文件系统,排除/mnt但在/mnt中包含特定路径,看起来建议使用--filter而不是--include和--exclude,但是,我似乎无法让它来做我的出价,例如:

rsync -aA -H --numeric-ids -v --progress --delete \
  --filter="merge /tmp/mergefilter.txt" /  /mnt/data/mybackup/

我的/tmp/mergefilter.txt说:

+ /mnt/data/i-want-to-rsyncthisdirectory/
- /dev
- /sys/
- /tmp/
- /run/
- /mnt/
- /proc/
- /media/
- /var/swap
- /lost+found/

以" - "开头的所有路径被忽略,但我/mnt/data/i-want-to-rsyncthisdirectory/的包含似乎永远不会得到rsync' d。订单和/或包含/排除尾部斜杠似乎不会改变与我想要包含的路径相关的行为。

编辑:请注意,我要根据指定为/

的来源备份/ etc / usr / var等

感谢任何指导,因为手册页有点像雷区......

3 个答案:

答案 0 :(得分:5)

对我来说,这个命令正在完成这项工作:

rsync -aA -H --numeric-ids -v --progress --delete \
--filter="+ /mnt/data/i-want-to-rsyncthisdirectory/" \
--filter="- *" . /mnt/data/mybackup/

基本上,我在相关目录中使用了+过滤器并且放弃了所有其他目录(正如您在给定示例中所做的那样)。

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

答案 1 :(得分:5)

这个问题很老了,但我认为这可能会对你有所帮助:

(来自rsync 3.1.2手册)

  

注意,当使用--recursive(-r)选项(由-a隐含)时,每个路径的每个子组件都从          自上而下,所以包含/排除模式以递归方式应用于每个子组件的全名(例如包括“/ foo / bar / baz”)          不得排除子组件“/ foo”和“/ foo / bar”)。排除模式实际上使目录交换机短路 -          rsync找到要发送的文件时的sal阶段。如果模式排除特定的父目录,则它可以渲染得更深          包含模式无效,因为rsync没有通过层次结构的排除部分下降。这是特别的          使用尾随'*'规则时很重要。例如,这不起作用:

         + /some/path/this-file-will-not-be-found
         + /file-is-included
         - *
     

这会失败,因为'*'规则排除了父目录“some”,因此rsync永远不会访问“some”中的任何文件          或“some / path”目录。一种解决方案是使用单个规则要求包含层次结构中的所有目录:          “+ * /”(把它放在“ - *”规则之前的某个地方),也许使用--prune-empty-dirs选项。另一个解决方案是添加spe-          cific包括所有需要访问的父目录的规则。例如,这套规则运行正常:

         + /some/
         + /some/path/
         + /some/path/this-file-is-found
         + /file-also-included
         - *

我在原来的答案中提出了一些没有错的东西(我测试了它)。我重现了一棵类似于你的树,这个解决方案现在应该可以工作了:

+ /mnt/
+ /mnt/data/
+ /mnt/data/i-want-to-rsyncthisdirectory/
- /mnt/data/*
- /mnt/*
- /dev
- /sys/
- /tmp/
- /run/
- /proc/
- /media/
- /var/swap
- /lost+found/

说明:

(最后只重写手册,但正如你所说,手册有点神秘)

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

请注意每个子文件夹排除结尾处的 * 。它会阻止rsync备份这些子文件夹中的文件和文件夹,这是你想要的。

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

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

+ /mnt/
+ /mnt/data/
+ /mnt/data/i-want-to-rsyncthisdirectory/***
- /mnt/**

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

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

--verbose --verbose

结合 - dry-run 参数,你应该能够调试你的问题:)

答案 2 :(得分:0)

如果其他人正在与我抗争,我已经设法使以下内容起作用。就我而言,我选择性地同步了另一台服务器的存储库。

在文件中放置过滤器:

+ epel/
+ epel/7/
+ epel/7/x86_64/
+ epel/7/x86_64/Packages**
+ epel/7/x86_64/repodata**
- **

然后可以根据需要与所有内容进行同步:

cd /srv/repo
rsync -rvzP -f 'merge /home/user/sync-filter.txt' ./ user@remote:/srv/repo/

最初,我使用epel/7/x86_64/Packages/**设置了过滤器文件,由于**之前的斜杠,该文件无法正常工作。 删除/ 使其如期出现!