我刚刚开始尝试使用 rsync 将一些文件从几台 Linux 机器备份到 Windows 服务器,该服务器运行其余的备份系统。经过大量的阅读和实验,我终于在其中一台 Linux 机器(Centos)上成功运行了它,所以我将脚本复制到另一台机器(Debian),编辑了一些路径并尝试运行它。与在第一台机器上运行的方式不同,我得到了以下结果:
building file list ...
1 file to consider
sent 36 bytes received 16 bytes 11.56 bytes/sec
total size is 0 speedup is 0.00
有问题的脚本是:
#! /bin/sh
/usr/bin/rsync \
--progress \
--recursive \
-t \
--delete-excluded \
--filter="- .cpan/***" \
--filter="- include/***" \
--filter="- cache/***" \
--filter="- lib/***" \
--filter="- cvs/***" \
--filter="+ /BayesTraining/***" \
--filter="+ /BogoTraining/***" \
--filter="+ /etc/***" \
--filter="+ /var/***" \
--filter="+ /root/***" \
--filter="+ /boot/***" \
--filter="+ /usr/local/***" \
--filter="+ /home/***" \
--filter="- *" \
/ \
rsync://myserver/targetfolder
仅当我删除最后一个过滤参数时它才会开始发送文件,但随后它会发送比我想要的多得多的文件。
我哪里做错了,需要改什么?(在有人问之前,我没有使用 SSH 上的 rsync,因为 Windows 服务器上还没有 SSH 服务。小步骤……)
编辑:rsync --version 显示
Centos: rsync version 2.6.8 protocol version 29
Debian: rsync version 2.6.4 protocol version 29
解决方案:感谢 pavium 指出我忽略了手册页中的关键部分(已重新格式化以便于阅读):
a trailing "dir_name/***" will match both the directory (as if "dir_name/"
had been specified) and everything in the directory (as if "dir_name/**"
had been specified). This behavior was added in version 2.6.7.
解决方案是为我想要包含的每个目录创建以下规则:
--filter="+ /dirname/"
--filter="+ /direname/**"
答案1
最后一个过滤项可能是你的问题(好吧,我认为你知道那)。我在 2.6.9 手册页中发现了以下内容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 选项。另一种解决方案是为所有需要访问的父目录添加特定的包含规则。例如,这组规则可以正常工作:
+ /some/
+ /some/path/
+ /some/path/this-file-is-found
+ /file-also-included
- *
因此,-* 排除路径不是过滤规则中明确包含的内容。手册页还告诉我,尾随的“dir_name/***”行为(即会已启用这些路径)是在 2.6.7 版本中添加的(您的 Debian 版本较早)
答案2
心灵调试模式已激活:
Bash 可能正在将 扩展*
为当前目录中所有文件的列表,因此 rsync 看不到它*
看到的file1 file2 file3
。
尝试转义*
- --filter="- \*" \
,或者--filter='- *' \
应该可以解决问题。
答案3
在您的 CentOS 和 Debian 机器上运行“rsync --version”,并比较结果。Debian 版本可能比较旧吗?这可能是该特定版本的错误,也可能是该机器上的编译方式错误。