首页 > 解决方案 > 带有删除选项但不包括子文件夹的 Rsync

问题描述

我需要使用该--delete选项从远程服务器目录(源)同步本地目录(目标)。我有这个:

本地目录是/home/user/config并进入它

removeit.txt
bar.csv
foo.h
config.conf
scripts <- Is a directory
logs <- Is adirectory

远程目录是config并进入它

bar.csv
foo.h

我想在 rsync 之后在本地目录中

bar.csv
foo.h
config.conf
scripts <- Is a directory
logs <- Is adirectory

我已经使用多个选项进行了测试,但我无法根据我的需要获得完整的 rsync 命令。

rsync -avz --min-size=1 --delete -e "ssh" user@example.com:./config/ ./config --exclude ./config/scripts --exclude ./config/logs --exclude ./config/device.conf --dry-run

带有包含文件的列表

rsync -avz --min-size=1 --include-from=list --exclude=* --delete-excluded -e "ssh" user@example.com:.config/ config/

但没有什么能像我预期的那样工作。目标中的子文件夹将被删除。

标签: rsync

解决方案


rsync的手册页有一个关于“包含/排除模式规则”的部分,您应该查看它。特别是,您似乎正在使用./与您的 shell 工作目录相关的目录来引用该目录,而该目录不会按您想要的方式工作。

这是文档的相关部分:

如果模式以 / 开头,则它被锚定到文件层次结构中的特定位置,否则它与路径名的末尾匹配。这类似于正则表达式中的前导 ^。因此 /foo 将在“传输的根”(对于全局规则)或合并文件的目录(对于每个目录规则)中匹配名称“foo”。不合格的 foo 将匹配树中任何位置的名称“foo”,因为该算法是从上到下递归应用的;它的行为就像每个路径组件在文件名的末尾都有一个转折。即使是未锚定的“sub/foo”也会匹配层次结构中在名为“sub”的目录中找到“foo”的任何点。

您正在使用的模式可能会导致 rsync 查找一个字面上称为.的文件夹,该文件夹包含一个名为的文件或文件夹scripts或其他任何内容。

尝试用排除模式中的相对./config/部分替换/。这会将模式锚定在您正在同步的目录的“传输根目录”中。换句话说,试试这个:

rsync -avz --min-size=1 --delete -e "ssh" user@example.com:./config/ ./config --exclude /scripts --exclude /logs --exclude /device.conf --dry-run

我希望这行得通。如果检查还为时不晚,请告诉我这是否对您有用。


推荐阅读