Como posso usar o rsync para duplicar uma árvore de diretórios, criando hardlinks para arquivos?


23

De tempos em tempos, tenho que executar várias grandes alterações de migração nos arquivos de dados no meu servidor e estou procurando uma boa maneira de fazer isso. Eu estava pensando em usar o rsync para duplicar minha estrutura de diretórios começando na pasta de dados raiz, criando links físicos para todos os arquivos originais (alguns deles são grandes) e posso sobrescrever na árvore de destino apenas os arquivos que precisam ser migrados. No final, eu posso alternar com segurança dos arquivos antigos para os novos com duas mvoperações.

No entanto, não consigo obter o rsync para fazer isso. eu tentei

rsync -a --link-dest=$DATA $DATA $DATA/../upgrade_tmp

mas, em vez de criar links físicos para arquivos, o rsync os copia completamente. Existe um problema ao usar o mesmo diretório de origem e link-dest?

Respostas:


21

rsync é uma ferramenta poderosa, mas infelizmente é estranhamente exigente quanto a alguns de seus nomes de caminho.

Se $DATAfor um caminho absoluto (ou seja, começa com a /), a linha de comando correta a ser usada é:

rsync -a --link-dest=$DATA $DATA/ $DATA/../upgrade_tmp

[Agora, apenas um breve aparte sobre rsynca estranheza de. Observe a trilha /adicionada ao argumento de origem. Isso diz rsyncpara trabalhar com o conteúdo do diretório de origem, em vez de com o próprio diretório de origem. (Suponho que $DATAainda não contenha um final /). Nesse caso, queremos trabalhar com o conteúdo e adicionamos o final /.]

Se, por outro lado, $DATAfor um caminho relativo (ou seja, não começa com a /), o comentário de Sean R --link-desté sobre: ​​O caminho de destino do link é interpretado em relação ao caminho de destino , portanto, você deve usar o seguinte:

rsync -a --link-dest=../`basename $DATA` $DATA/ $DATA/../upgrade_tmp

EDITAR

Uma observação final: verifica-se que a segunda rsynclinha de comando que eu dei deve funcionar independentemente de $DATAser um caminho absoluto, uma vez basenameque não se importa se um caminho é absoluto ou relativo.


1
Apenas uma barra faltando, quem teria pensado nisso… Obrigado pela boa explicação!
Jean-Philippe Pellet

Obrigado por isso, tentei seguir várias instruções de backup incremental, como esta, e não encontrei nenhuma menção a essa peculiaridade. Essa foi a única coisa que realmente garantiu que os arquivos estavam sendo vinculados. Verificando que a contagem ref foi> 1 e inode números eram os mesmos comls -ilah
Walf

I utilizado este em conjunto com a função relPath () descrito no unix.stackexchange.com/a/85068/57414 a cópia de segurança de um $SOURCEdirectório numa $TARGETdir assim:SOURCE='abs_path_to_backup'; TARGET='.'; rsync -a --link-dest=$(relpath $TARGET $SOURCE) $SOURCE/ $TARGET/
Nathan S. Watson-Haigh

13

O que você quer é "cp -al":

cp -al $DATA/ $DATA/../upgrade_tmp/
  • -a se repete como rsync -a
  • -l vinculará os arquivos ao invés de copiá-los.

1
cp -alinfelizmente não está disponível no meu sistema (Mac OS X 10.6). Em vez disso, vou usar pax ...
Jean-Philippe Pellet

7

A --link-destopção in rsyncé relativa ao diretório de destino , não ao diretório atual. Então, o que você quer é:

rsync -a --link-dest=../`basename $DATA` $DATA $DATA/../upgrade_tmp

Opa, eu quis dizer basename, originalmente eu tinha dirname.
Sean Reifschneider

1
A página de manual diz que a --link-destopção, se relativa , é relativa ao diretório de destino. No meu caso, é absoluto. Mesmo torná-lo relativo ao diretório de destino não faz esse trabalho.
Jean-Philippe Pellet

7

Acontece que é mais difícil fazer isso do rsyncque com outras ferramentas. A resposta correta rsyncé a de Steven Monai, mas a maneira mais fácil de fazer isso é usar um cp -alou pax -rwlem sistemas onde -lnão é uma opção válida para cp:

pax -rwl $DATA $DATA/../upgrade_tmp

ou

cp -al $DATA/ $DATA/../upgrade_tmp/

4

Funciona para mim:

$ rsync --hard-links --recursive --link-dest=/local user@host:/remote/ /local

Eu uso o rsync versão 3.1.0.

Do homem :

--hard-links

Diz ao rsync para procurar arquivos vinculados na transferência, sem essa opção, os arquivos vinculados na transferência são tratados como se fossem arquivos separados.

--link-dest = DIR

Arquivos inalterados são vinculados do DIR ao diretório de destino. Os arquivos devem ser idênticos em todos os atributos preservados (por exemplo, permissões, possivelmente propriedade) para que os arquivos sejam vinculados


2
Somente o snippet de código não é suficiente, explique o que faz e por quê.
peterh diz restabelecer Monica

--hard-links Diz ao rsync para procurar arquivos vinculados na transferência, sem essa opção, os arquivos vinculados na transferência são tratados como se fossem arquivos separados. --link-dest = DIR Arquivos inalterados são vinculados do DIR ao diretório de destino. Os arquivos devem ser idênticos em todos os atributos preservados (por exemplo, permissões, possivelmente propriedade) para que os arquivos sejam vinculados.
Alexander Fedorov

1
Maravilhoso. Obrigado. Na verdade, encontrei sua resposta na fila "baixa qualidade". Isso significa que houve uma votação se sua resposta deve ser excluída ou não. Mas não apenas o perigo das exclusões é um motivo para tentar dar uma resposta "humana" bem formatada, mas também ajuda muito se você deseja coletar votos positivos.
peterh diz restabelecer Monica


2

Primeiro, crie os diretórios apenas no destino:

rsync -av --include '*/' --exclude '*' /source/ /destination/

Em seguida, vincule apenas os arquivos:

cd /source
find . -type f -exec ln -v {} /destination/{} \;

Obrigado - na verdade, eu poderia usar paxcomo mostrado no meu comentário acima, o que parece mais fácil.
Jean-Philippe Pellet

1

Use a opção -H para preservar os Hardlinks e leia a página de manual.


1
-H não funciona. Não tenho hardlinks para preservar na minha árvore de origem, só quero uma cópia simples da minha árvore de origem, onde, na cópia, todos os arquivos são vinculados aos arquivos originais. Desculpe na minha pergunta original não estava claro ...
Jean-Philippe Pellet

"leia a página de manual" é uma resposta? :-)
meduz
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.