前段时间在备份服务器时,由于备份策略的变化,对 rsync 的 exclude patterns 进行了一些更加深入的探索。

这篇文章将介绍如何设计 rsync 的 exclude patterns 以排除特定目录或文件。

命令介绍

rsync 是 Linux 和 Unix 中常用的文件复制和同步命令,相比 cp 命令而言更加高效和完善,其优点包括但不限于:

  • 增量复制:rsync 只会复制那些自上次同步后更改的文件部分,极大地减少了数据传输量。例如 a 文件已经同步过一次并且没有发生变化,则 rsync 会跳过。同样,rsync 也会进行完整性检查以确定传输的数据无误。
  • 保留属性:rsync 可以保持文件的权限、时间戳、软硬链接、所有权等属性。
  • 灵活的过滤规则:支持使用包括和排除规则来选择同步的文件或目录。

排除规则

rsync 通过参数 --exclude--exclude-from 指定排除的文件模式。其中 --exclude-from 用于指定包含排除模式的文件(包含多个排除规则)。

排除指定文件

输入文件名称(如 123.txt)即可排除所有命名为 123.txt 的文件。

排除特定尾缀的文件

通过 *.xxx 排除包含特定尾缀的文件,例如:

  • *.txt 排除所有以 .txt 结尾的文件。
  • *vcf 排除所有以 vcf 结尾的文件。注意这里并不推荐这样做,因为这也会排除掉所有以 vcf 结尾的目录,例如:
    • source/dir1/dir_vcf/xxx,这里 dir_vcf 及其中的所有文件也会被排除。

因此在根据尾缀排除文件时,最好添加尾缀前的 . 以避免其他文件夹的意外排除。

同理也可通过前缀进行文件排除,例如 SRR* 等,但同样地,这会排除符合该条件的所有目录。因此请谨慎使用

排除隐藏文件及文件夹

通过 .* 排除所有隐藏文件及隐藏文件夹

排除特定文件夹

直接使用文件夹名称,例如 anaconda3 等。但注意,如果有与该文件夹名同名的文件,那么该文件也会被排除,例如:

  • 使用 juse 时,source/juse/(目录)会被排除,此外 source/other/juse(文件名为 juse)也会被排除。

因此如果你想排除特定文件夹但又担心具有同名文件,两个好的权衡方式是:

  • 添加该目录先前的信息,例如你已经知道其位于其他文件夹中:dir1/dir2(排除位于 dir1 下的 dir2)。
  • 排除该目录中的所有文件,并保留空文件夹:dir2/**,该做法更加推荐,因为你也可以保留下 ‘哪些文件夹被排除’ 这个信息。

这里使用两个星号是为了和之后的跨多目录匹配相一致,但其实只用一个 * 的效果是一样的。

跨目录排除匹配的文件夹

该方法的应用场景如下:

用户 juse 的目录里存在多个 work 文件夹,juse 想将它们全部排除掉,但是他认为仅使用 work/** 并不妥当,因为其他人的 work 文件夹中可能存在需要备份的文件,而根据单个目录路径进行排除也存在困难,因为 juse 目录中的 work 文件夹很多且位置不一。

  • /juse/dir1/work/
  • /juse/work/
  • /juse/dir2/dir3/work/

此时可以通过使用 juse**/work 排除 juse 目录下所有 work 子目录。请注意仅使用单个 * 时无法实现跨目录匹配

  • juse/*/work 仅能识别到 /juse/dir1/work/,无法识别 /juse/dir2/dir3/work/

而使用 juse/**/work 则无法识别到 juse 目录下的 work 文件夹,可以通过去除第一个斜杠避免该问题。

相比之下 du 命令可以通过单个星号实现跨多个目录匹配,同时两个星号也不影响 du 的使用。

rsync 使用建议

首先需要明确一点,rsync 以 source 目录作为根目录进行同步操作,因此并不会因为先前的绝对路径中存在排除模式就导致同步失败,例如:

1
rsync -av --exclude 'juse' /juse/dir1/ /pathto/destination/

上述命令并不会导致 /juse/dir1/ 中的文件全部无法同步,因为其并不会考虑源目录本身的路径信息。

此外,在使用 rsync 推荐使用以下一些参数:

  • -av:归档模式 + 输出更多信息,前者保证 rsync 递归复制目录并保留文件的各种属性,后者有助于监控同步过程。
  • -z:在数据传输过程中进行压缩,在慢速网络中进行同步时建议启用。
  • --bwlimit:限制带宽(传输速度),避免影响其他进程。
  • --delete & --delete-excluded:前者删除目标文件夹中源文件夹里不存在的文件,后者删除目标文件夹中被排除模式匹配的文件,适合需要完全同步时使用。

注意 rsync 可以通过 --exclude-from 使用多个排除模式。