排除rsync中的一个目录但包含一个子目录

33

我正在尝试使用rsync将一个项目复制到服务器上。 我有一些特定于项目的安装脚本在子目录中

project/specs/install/project1

我想要做的是在排除project/specs目录中的所有内容,但包括项目特定的安装目录:project/specs/install/project1

rsync -avz --delete --include=specs/install/project1 \
    --exclude=specs/* /srv/http/projects/project/ \
     user@server.com:~/projects/project

但是这样做会排除specs目录的内容,但不会包含install/project1目录的内容。

我已经尝试了所有方法,但似乎无法使其正常工作。


1
刚在linuxquestions.org上找到了一个类似的问题,或许可以帮到你:http://www.linuxquestions.org/questions/linux-software-2/rsync-include-exclude-problems-636504/ - Chris
1
谢谢,问题解决了!Rsync有时候的逻辑确实很奇怪。 - user1036651
1
重复项:https://dev59.com/7lzUa4cB1Zd3GeqP6cRW#7961687 - Joao Figueiredo
2
--include和--exclude的顺序重要吗?更新:我自己回答了这个问题:它确实很重要。我无法在--include之前使用--exclude使其正常工作,但在--exclude之前使用--include可以正常工作。 - Geremia
3个回答

40

有时候只是一些细节问题。

只需在包含模式结尾处添加斜杠(/),它就会起作用:

rsync -avz --delete --include=specs/install/project1/ \
    --exclude=specs/* /srv/http/projects/project/ \
    user@server.com:~/projects/project

或者,另一种方法是准备一个类似于这样的过滤文件:

$ cat << EOF >pattern.txt
> + specs/install/project1/
> - specs/*
> EOF

然后使用--filter选项:

rsync -avz --delete --filter=". pattern.txt" \
    /srv/http/projects/project/ \
    user@server.com:~/projects/project

欲了解更多信息,请前往rsync(1)手册页中的FILTER RULES部分。


2
过滤规则确实是处理复杂问题的唯一明智方式,比如“排除所有.git目录”。 - Olivier 'Ölbaum' Scherler
结尾处的斜杠在我的包含模式中并不必要。谢谢! - Yaroslav Nikitenko

15

另一个解决方案在这里不起作用。


可靠的方法

您别无选择,只能手动下降每个子目录的级别。没有包括不想要的文件的风险,因为rsync不会包括所包含目录的文件。

1)创建一个包含筛选规则的文件,例如 "include_filter.txt":

+ /specs/
+ /specs/install/
+ /specs/install/project1/***
- /specs/**

2) 运行它:

rsync -avz --delete --include-from=include_filter.txt \
    /srv/http/projects/project/ \
    user@server.com:~/projects/project
  • 不要忘记起始斜杠"/",否则您可能会匹配到名为 "**/specs/install/project1/" 的子目录。
  • 通过选择包含类型过滤器(--include-from=FILE),起始加号"+"实际上是可选的,因为这是没有加号的默认操作。(您可以使用--exclude-from=FILE默认情况下有相反的减号 "-")
  • 双星号“**”表示“任何路径”
  • 三个星号“***”表示“任何路径,包括此目录”

简便方法

您可以以"*/"开头启动筛选器,使rsync下降到所有子级。这很方便,但是:

  • 所有目录都将被包括在内,即使是空的。这可以通过rysnc选项 -m来解决,但是那样所有空目录都将被跳过。

1)创建一个包含过滤器文件,例如“include_filter.txt”:

+ /**/
+ /specs/install/project1/***
- /specs/**

2) 运行它:

rsync -avzm --delete --include-from=include_filter.txt \
    /srv/http/projects/project/ \
    user@server.com:~/projects/project

请注意新增的选项 -m。


2

--include--exclude的顺序影响了包含或排除哪些内容。
当有特定的子目录需要被包含时,需要将它们放在首位。
类似的帖子可以在这里找到。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接