Por que o primeiro comando rsync está funcionando perfeitamente criando um clone de /tmp/data para /tmp/bak usando hardlinks, mas o segundo cria um clone copiando bytes em vez de hardlinking?
rsync -a --link-dest=/tmp/data /tmp/data/ /tmp/bak/ # HARDLINKS
rsync -a -R --link-dest=/tmp/data /tmp/data/ /tmp/bak/ # REGULAR COPIES
Etapas para testar/reproduzir
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.
Ao usar o sinalizador
-R
(--relative
), todos os caminhos são prefixados com o caminho de origem, incluindo qualquer--link-dest
caminho.Trabalhando isso com o seu exemplo,
o que isso significa é que o caminho link-dest se torna
/tmp/data/tmp/data
. (Você pode ver isso mais claramente comcp -al /tmp/data /tmp/link
e usandostrace -f rsync ... --link-dest=/tmp/link
.)A solução neste caso é usar
--link-dest=/
para que o ponto de partida gerado se torne o seu desejado--link-dest=/tmp/data
Essa é uma pergunta interessante.
Quando você usa
rsync -R
, ele copia otmp/data
para o diretório de destino.O problema é que, quando o rsync copiar, ele verificará primeiro se o arquivo existe no diretório fornecido pelo
--link-dest
:Ou seja, ele será comparado
/tmp/bak/*
com/tmp/data/*
.O problema é que, ao iniciar o
rsync -R
comando, ofoo
arquivo não estará em um local que possa ser comparado com /tmp/data/ para fazer o link, ele estará em/tmp/bak/tmp/data/foo
, enquanto o rsync, estupidamente, só faria hardlink para ele se é a raiz dos diretórios fornecidos (nesse exemplo,/tmp/data
e/tmp/bak
).