如何使用 RSYNC 获取未更改的文件硬链接和附加文件复制到本地 + 附加?

San*_* P. 5 linux sync rsync file-transfer command-line

我试图找出一种使用 rsync(一次或多次)和可能的其他命令(例如 cp -lr)来完成以下操作的方法:

  1. 将远程文件夹 A 同步到本地文件夹 B
  2. 我已经有一个本地文件夹 C,它是 A 的先前同步
  3. 我希望在 C 和 A 之间未更改的文件在 B 中创建为硬链接
  4. 我希望将 A 中的新文件传输回 B
  5. 我希望已在 A 中删除的文件,而不是在 B 中进行硬链接或硬链接后删除。
  6. 我希望 A 中已修改(通过附加数据)的文件从 C 本地复制到 B,并且只传输附加字节并将其附加到新副本。

我知道的一些限制可能有助于找到解决方案:

  • A中有两种文件:
    1. 不可变的,要么是新建的,要么是删除的。
    2. 可变的,总是通过附加数据来修改,也可以删除。
  • 这两种文件很容易区分,因为每个组都有一个固定的前缀,因此任何命令都可以针对任一组或两者。

我目前的解决方案是使用

rsync -av --link-dest C remote:A B
Run Code Online (Sandbox Code Playgroud)

但这有一个缺点,即附加文件被完全传输,体积增加了 10 倍以上。

欢迎对此解决方案进行任何改进,如果所有传输都使用 rsync 完成,效果会更好。

注意:使用几轮 rsync 来实现它是可以的,只要 C 没有改变,在这种意义上缺乏原子性就不是问题。

San*_* P. 1

好吧,我认为我无法完成此任务,直到我最近发现了一个可以使用 rsync 完成的绝妙技巧,并且由于一段时间以来没有人回答,我将介绍我的解决方案。

诀窍是当您使用以下参数时:

rsync --suffix "" --backup-dir "." ...
Run Code Online (Sandbox Code Playgroud)

这会导致 rsync 在修改文件之前对其进行备份,但备份结果是就地的,因此您实际上是在修改文件之前复制文件。这允许您更改硬链接的文件而不更改原始文件。

然后,完成所需行为的顺序可能如下:

# locally hard-link the mutable files
rsync -ahv --link-dest C --include-from MUTABLE_FILES.filter C/* B

# copy locally + append remotely changed files 
# (also delete mutable files that disappeared at remote location A)
rsync -ahbv --suffix "" --backup-dir "." --append-verify \
      --include-from MUTABLE_FILES.filter --delete A/* B 

# now hard-link locally + transfer immutable files
rsync -ahv --link-dest C --include-from IMMUTABLE_FILES.filter A/* B
Run Code Online (Sandbox Code Playgroud)

这可能可以通过前两个步骤来解决,而不使用过滤器,但在我的特定用例中,为了保证最终目标的一致性,我需要在不可变文件之前传输可变文件,而 rsync 完成的默认字母顺序并不能保证这一点我的情况。我需要它的原因是可变文件可能会被删除并被不可变文件替换。如果我没有传输不可变文件,因为它目前不存在,但可变文件在我到达它之前就消失了,那么我什么都没有,并且丢失了数据。