我正在尝试使用 rsync 备份我的 Raspberry Pi 上的网站,但是当我指定包含和排除时,它不会递归到子目录中。我使用以下命令:
rsync -rva html/ /media/pi/DEC6-5E68/html/ --include '.htaccess' --include '*.html' --include '*.php' --exclude '*'
但尽管有“r”选项,我还是只备份了上层,而不是递归。我想我对 Linux 通配符有一个基本的误解。如果我省略任何包含或排除参数,它就会递归。
答案1
无论何时遇到子目录,它都会被--exclude '*'
语句排除并且rsync
不会下降。
手册中提到了此行为,并提供了解决方案。来自man 1 rsync
:
请注意,当使用
--recursive
(-r
) 选项(由 暗示-a
)时,每个路径的每个子组件都会从上向下访问,因此包含/排除模式会递归应用于每个子组件的全名(例如,包含/foo/bar/baz
子组件/foo
并且不能排除)。排除模式实际上会在找到要发送的文件/foo/bar
时缩短目录遍历阶段。如果模式排除了特定的父目录,则它可能会使更深的包含模式无效,因为没有通过层次结构中排除的部分。这在使用尾随规则时尤为重要。例如,这将不起作用:rsync
rsync
*
+ /some/path/this-file-will-not-be-found + /file-is-included - *
这会失败,因为父目录
some
被规则排除*
,因此永远不会访问或目录rsync
中的任何文件。一种解决方案是要求使用单个规则包含层次结构中的所有目录:(将其放在规则之前的某个位置),也许可以使用选项。[…]some
some/path
+ */
- *
--prune-empty-dirs
--filter
注意本手册的这一部分使用( -f
) 选项的语法,其中+
类似于--include
并且-
类似于--exclude
。建议的规则+ */
可能在您的命令行中显示为--include '*/'
。引用非常重要,它可以防止*/
被 shell 扩展。
为了完整性,手册中关于有用选项的说明如下--prune-empty-dirs
:
-m
,--prune-empty-dirs
此选项告知接收方rsync
从文件列表中删除空目录,包括没有非目录子目录的嵌套目录。当发送方rsync
使用包含/排除/过滤规则递归扫描文件层次结构时,这有利于避免创建一堆无用的目录。[…]
因此你的命令可能是
rsync -rmva html/ /media/pi/DEC6-5E68/html/ \
--include '*/' \
--include '.htaccess' \
--include '*.html' \
--include '*.php' \
--exclude '*'
您可以省略目的地(/media/pi/DEC6-5E68/html/
在您的情况下),以便rsync
只列表将被复制的内容。这样您就可以验证我的命令是否是您需要的。