为什么添加 --relative 后 --link-dest 停止创建硬链接?

为什么添加 --relative 后 --link-dest 停止创建硬链接?

为什么第一个 rsync 命令可以完美地创建 /tmp/data 到 /tmp/bak 的克隆使用硬链接但第二个创建了一个克隆复制字节而不是硬链接?

rsync -a    --link-dest=/tmp/data  /tmp/data/  /tmp/bak/ # HARDLINKS
rsync -a -R --link-dest=/tmp/data  /tmp/data/  /tmp/bak/ # REGULAR COPIES

测试/重现的步骤

cd /tmp/
rm -rf data bak                                                                                                                     
mkdir data bak 
echo foo > data/foo 
stat /tmp/data/foo | grep Inode
rsync -a    --link-dest=/tmp/data  /tmp/data/  /tmp/bak/
stat /tmp/bak/foo  | grep Inode                        
### Note that the inode is the same as above.

rm bak/*                       
rsync -a -R --link-dest=/tmp/data  /tmp/data/   /tmp/bak/
stat /tmp/bak/tmp/data/foo | grep Inode      
### Note that the inode is different.

答案1

使用-R( --relative) 标志时,所有路径都会以源路径为前缀,包括任何--link-dest路径。

通过你的例子来解决这个问题,

rsync -a -R --link-dest=/tmp/data /tmp/data/ /tmp/bak/

这意味着链接目标路径变为/tmp/data/tmp/data。 (您可以cp -al /tmp/data /tmp/link使用 和 使用更清楚地看到这一点strace -f rsync ... --link-dest=/tmp/link。)

本例中的解决方案是使用--link-dest=/,以便生成的起点成为您想要的--link-dest=/tmp/data

rsync -a -R --link-dest=/ /tmp/data/ /tmp/bak/
stat /tmp/bak/tmp/data/foo | grep Inode    # Same inode as source, with Links: 2

答案2

这是一个有趣的问题。

当您使用 时rsync -R,它会将 复制tmp/data到目标目录中。

问题是,当 rsync 复制时,它会首先检查文件是否存在于以下给出的目录中--link-dest

意思是,它将/tmp/bak/*与进行比较/tmp/data/*

问题是,当您启动rsync -R命令时,该foo文件不会位于可以与 /tmp/data/ 进行比较来进行链接的位置,它将位于/tmp/bak/tmp/data/foo,而 rsync 愚蠢地只会在以下情况下为其进行硬链接:它是给定目录的根(在该示例中为/tmp/data/tmp/bak)。

相关内容