我正在尝试找出一种方法来使用 rsync(一次或多次)以及可能的其他命令(例如 cp -lr)来完成以下操作:
- 将远程文件夹A同步到本地文件夹B
- 我已经有一个本地文件夹 C,它是 A 的先前同步
- 我希望在 B 中创建 C 和 A 之间未更改的文件作为硬链接
- 我想将 A 中的新文件传输回 B
- 我希望在 A 中已删除的文件不要在 B 中进行硬链接或者进行硬链接然后被删除。
- 我想要将在 A 中修改过(通过附加数据)的文件从 C 本地复制到 B,并且仅将附加的字节传输并附加到新副本中。
据我所知,以下几个限制条件可能有助于找到解决方案:
- A中有2种文件:
- 不可变的,要么新建,要么删除。
- 可变的,总是通过附加数据来修改,也可以被删除。
- 这两种文件很容易区分,因为每个组都有固定的前缀,所以任何命令都可以针对任一组或同时针对两者。
我当前的解决方案是使用
rsync -av --link-dest C remote:A B
但这样做的缺点是附加文件会被完全传输,从而导致体积增加 10 倍以上。
欢迎对此解决方案进行任何改进,如果所有传输都使用 rsync 完成就更好了。
注意:使用多轮 rsync 来实现它是可以的,只要 C 没有改变,缺乏原子性就不是问题。
答案1
好吧,我之前并不认为我能做到这一点,直到最近我发现了一个可以用 rsync 实现的巧妙技巧,而且因为很久没有人回答,所以我将提出我的解决方案。
诀窍在于使用以下参数:
rsync --suffix "" --backup-dir "." ...
这会导致 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
这个问题可能可以通过前两个步骤解决,无需使用过滤器,但在我的特定用例中,为了保证最终目标的一致性,我需要先传输可变文件,然后再传输不可变文件,而 rsync 默认的字母顺序在我的例子中无法保证这一点。我需要这样做的原因是可变文件可能会被删除并被不可变文件替换。如果我没有传输不可变文件,因为它当时不存在,但可变文件在我到达之前就消失了,那么我什么都没有了,数据也丢失了。