我在 Linux 系统上使用 rsync 在本地磁盘和连接的 USB 驱动器之间同步目录。我遇到的问题是,每天在服务器上创建备份的第三方系统实际上会更改备份深处嵌套的目录的名称。此目录包含备份所需的大部分数据。当 rsync 查看目录时,它会发现名称已更改,并将其视为一个全新的目录。因此,我 USB 驱动器上的 rsync 副本在每天运行时都会有一个新目录。
我已经编写了可以实际将目录名称改回来的脚本,但是这样做很麻烦!
我正在寻找一种“优雅”的方式来处理这个问题。是否可以创建一个指向目录的链接,该链接保持不变?是否可以配置 rsync 以检测目录是否相同,即使名称已更改?我相信以前有人必须处理这个问题!
答案1
一种方法是分两步进行。第一步,使用忽略模式 rsync 除相关目录之外的所有内容。第二步,仅 rsync 该目录,在 bash 中使用通配符来获取该目录,如下所示:
rsync -av /usr/lib/mydata/bigdatadir*/ /mnt/usbvolume/bigdatadir/
在源目录上使用尾部斜杠将导致 rsync 忽略目录名称,因为它将在内容目录的名称,而不是目录本身。当然,如果目录的名称带有固定前缀或后缀(如我上面的例子所示),这种通配符将最容易。如果不是,您可以编写一个脚本来找出目录的实际名称,然后执行更直接的操作,如下所示:
rsync -av /usr/lib/mydata/$BIGDATADIRNAME/ /mnt/usbvolume/bigdatadir/
最后,你的伪代码将是这样的:
- 查找 $BIGDATADIRNAME
- 像以前一样使用 Rsync 同步所有内容,但忽略 $BIGDATADIRNAME
- rsync 将内容$BIGDATADIRNAME 的
答案2
您可能能够使用 rsync 选项–比较目标=DIR,–copy-dest=DIR, 或者–link-dest=目录。它们允许您在接收端指定一个附加目录来查找丢失的文件。
例如,使用 --link-dest,rsync 将创建包含已更改文件的新副本或未更改文件的硬链接副本的目录的新版本。
要使用这些选项中的任何一个,您必须知道上次 rsync 运行中 USB 驱动器上的目录名称,因此您可能需要将 rsync 包装在一个脚本中,该脚本首先找出正确的目录名称。
您可能还想在创建新版本后使用 --delete-after 删除目录的旧版本。
答案3
rsync 本身无法完成您想要的操作,因为 rsync 唯一可用的元数据是目录名称和 MACtimes。
在 rsync 内部自动处理此问题的唯一方法是让 rsync 以某种方式拥有更多元数据。例如,Windows 上的 Microsoft DFS 复制通过使用分配给 NTFS 卷中文件的唯一 ID 来捕获文件(或目录)名称的更改来处理此问题。
您的不雅脚本可能是做您想做的事情的最简单的方法,而无需转储 rsync 并寻找其他工具。
使用符号链接不会起作用,因为连接点与目标目录的名称相关联(在这种情况下,目标目录名称将会更改)。您可以使用硬链接(与 inode 相关联),但您需要确保目录名称正在更改,而不仅仅是被删除并重新创建(这会为其分配不同的 inode)。