简体   繁体   English

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

[英]Using Rsync filter to include/exclude files

I'm trying to backup a filesystem, exclude /mnt but include a particular path within /mnt , it looks like using --filter is recommended over --include and --exclude, however I don't seem to be able to get it to do my bidding , example: 我正在尝试备份一个文件系统,排除/mnt但在/mnt包含一个特定的路径,看起来好像使用--filter建议使用--include和--exclude,但我似乎无法获得它来做我的出价,例如:

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

My /tmp/mergefilter.txt says: 我的/tmp/mergefilter.txt说:

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

All of the paths starting with "-" gets ignored, however my include for /mnt/data/i-want-to-rsyncthisdirectory/ seems to never get rsync 'd. 所有以“ - ”开头的路径都会被忽略,但是我的/mnt/data/i-want-to-rsyncthisdirectory/似乎永远不会得到rsync Order and/or including/excluding the trailing slash does not appear to change the behavior related to the path I want included. 顺序和/或包含/排除尾部斜杠似乎不会改变与我想要包含的路径相关的行为。

EDIT: Note that I do want to backup /etc /usr /var etc. as per the source specified as / 编辑:请注意,我确实要根据指定为/的源备份/ etc / usr / var等

Appreciate any guidance as the man page is a bit of a minefield... 感谢任何指导,因为手册页有点像雷区......

For me, this command is doing the job: 对我来说,这个命令正在完成这项工作:

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

Basically, I used a + filter for the directory in question and exlcude all the others (as you do in your given example). 基本上,我使用了一个+过滤器来讨论所讨论的目录并驱逐所有其他目录(正如你在给定的例子中所做的那样)。

There is no need to explicitly negate all the directories you do not want to sync. 无需明确否定您不想同步的所有目录。 Instead, you can ignore all except the one in question. 相反,您可以忽略所有问题之外的所有问题。

This question is quite old but I think this might help you: 这个问题很老了,但我认为这可能会对你有所帮助:

(from rsync 3.1.2 manual) (来自rsync 3.1.2手册)

Note that, when using the --recursive (-r) option (which is implied by -a), every subcomponent of every path is visited from the top down, so include/exclude patterns get applied recursively to each subcomponent's full name (eg to include "/foo/bar/baz" the subcomponents "/foo" and "/foo/bar" must not be excluded). 注意,当使用--recursive(-r)选项(由-a暗示)时,从上到下访问每个路径的每个子组件,因此包含/排除模式以递归方式应用于每个子组件的全名(例如,要包含“/ foo / bar / baz”,不得排除子组件“/ foo”和“/ foo / bar”。 The exclude patterns actually short-circuit the directory traver- sal stage when rsync finds the files to send. 当rsync找到要发送的文件时,排除模式实际上会使目录流量阶段短路。 If a pattern excludes a particular parent directory, it can render a deeper include pattern ineffectual because rsync did not descend through that excluded section of the hierarchy. 如果模式排除特定的父目录,则它可以呈现更深层的包含模式无效,因为rsync没有通过层次结构的排除部分下降。 This is particularly important when using a trailing '*' rule. 使用尾随'*'规则时,这一点尤为重要。 For instance, this won't work: 例如,这不起作用:

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

This fails because the parent directory "some" is excluded by the '*' rule, so rsync never visits any of the files in the "some" or "some/path" directories. 这失败是因为父目录“some”被'*'规则排除,因此rsync从不访问“some”或“some / path”目录中的任何文件。 One solution is to ask for all directories in the hierarchy to be included by using a single rule: "+ */" (put it somewhere before the "- *" rule), and perhaps use the --prune-empty-dirs option. 一种解决方案是通过使用单个规则要求包含层次结构中的所有目录:“+ * /”(将其放在“ - *”规则之前的某处),并且可能使用--prune-empty-dirs选项。 Another solution is to add spe- cific include rules for all the parent dirs that need to be visited. 另一种解决方案是为需要访问的所有父目录添加特定的包含规则。 For instance, this set of rules works fine: 例如,这套规则运行正常:

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

I proposed something in my original answer that does not wrong (I tested it). 我在原来的答案中提出了一些没有错的东西(我测试了它)。 I reproduce a tree similar to yours and this solution should work now: 我重现了一个类似于你的树,这个解决方案现在应该可以工作:

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

Explanations: 说明:

(only rewording the manual in the end but as you said the manual is a bit cryptic) (最后只重写手册,但正如你所说,手册有点神秘)

Rules are read from top to bottom each time a file must be transferred by rsync. 每次必须通过rsync传输文件时,都会从上到下读取规则。 But in your case /mnt/data/i-want-to-rsyncthisdirectory/ is not backed up because you exclude /mnt and this short-circuits your include rules. 但是在你的情况下/ mnt / data / i-want-to-rsyncthisdirectory /没有备份,因为你排除/ mnt并且这会使你的包含规则短路。 So the solution is to include each folder and subfolder until the folder you want to back up and then to exclude what you do not want to back up subfolder by subfolder. 因此,解决方案是将每个文件夹和子文件夹包括在要备份的文件夹中,然后排除您不希望通过子文件夹备份子文件夹的内容。

Note the * at the end of each subfolder exclusion. 请注意每个子文件夹排除结束时的* It will prevent rsync to back up the files and folder located in these subfolders which is what you want I think. 这将阻止rsync备份位于这些子文件夹中的文件和文件夹,这是您想要的。

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

You can even simplify this with the *** pattern that was added in version 2.6.7: 您甚至可以使用2.6.7版中添加的***模式简化此操作:

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

This operator allows you to use the ** wildcard for exclusion and consequently to have only one exclude line. 此运算符允许您使用**通配符进行排除,因此只有一个排除行。

I also discovered that you can understand which filter rules exclude/include each file or folder thanks to the following rsync arguments: 我还发现,由于以下rsync参数,您可以了解哪些过滤规则排除/包含每个文件或文件夹:

 --verbose --verbose 

Combined with the --dry-run argument you should be able to debug you problem :) 结合--dry-run参数你应该能够调试你的问题:)

In case someone else is battling with this as I am, I have managed to get the following to work. 如果其他人像我一样正在与此作斗争,我已设法让以下工作。 In my case I'm selectively sync repositories from another server. 在我的情况下,我有选择地从另一台服务器同步存储库。

Place filters in a file: 将过滤器放在文件中:

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

And can then sync everything as intended with: 然后可以按预期同步所有内容:

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

Initially, I had my filter file set up with epel/7/x86_64/Packages/** , which failed to work because of the trailing slash before the ** . 最初,我使用epel/7/x86_64/Packages/**设置了我的过滤器文件,由于**之前的斜杠,它无法工作。 Removing the / made it all spring in to life as intended! 卸下/使这一切成为春季以生命为目的!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM