Comment puis-je utiliser rsync pour dupliquer une arborescence de répertoires, créant des liens physiques vers des fichiers?

23

De temps en temps, je dois effectuer plusieurs changements de migration importants sur les fichiers de données sur mon serveur, et je cherche un bon moyen de le faire. Je pensais à utiliser rsync pour dupliquer ma structure de répertoires en commençant par le dossier de données racine, en créant des liens durs vers tous les fichiers d'origine (certains d'entre eux sont plutôt gros), et je peux remplacer dans l'arborescence de destination uniquement les fichiers qui doivent être migrés. En fin de compte, je peux passer en toute sécurité des anciens fichiers aux nouveaux fichiers en deux mvopérations.

Cependant, je n'arrive pas à obtenir rsync pour le faire. j'ai essayé

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

mais au lieu de créer des liens durs vers des fichiers, rsync les copie entièrement. Y a-t-il un problème avec le même répertoire source et link-dest?

Jean-Philippe Pellet
la source

Réponses:

21

rsync est un outil puissant, mais il est malheureusement étrangement pointilleux sur certains de ses chemins d'accès.

Si $DATAest un chemin absolu (c'est-à-dire qu'il commence par a /), alors la ligne de commande correcte à utiliser est:

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

[Maintenant, juste un bref aparté sur rsyncl'étrangeté de. Notez la fin /ajoutée à l'argument source. Cela indique rsyncde travailler avec le contenu du répertoire source, plutôt qu'avec le répertoire source lui-même. (Je suppose que $DATAcela ne contient pas déjà de fin /.) Dans ce cas, nous voulons travailler avec le contenu, alors nous ajoutons la fin /.]

Si, d'autre part, $DATAest un chemin relatif (c'est-à-dire qu'il ne commence pas par un /), alors le commentaire de Sean R --link-destest frappant: le chemin de destination du lien est interprété par rapport au chemin de destination , vous utiliserez donc ce qui suit:

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

MODIFIER

Une dernière note, il s'avère que la deuxième rsyncligne de commande que j'ai donnée devrait fonctionner indépendamment du fait qu'il $DATAs'agit d'un chemin absolu, car peu importe basenamesi un chemin est absolu ou relatif.

Steven Monday
la source
1
Juste une barre oblique manquante, qui aurait pensé à ça… Merci pour la belle explication!
Jean-Philippe Pellet du
Merci pour cela, j'ai essayé de suivre plusieurs instructions de sauvegarde incrémentielle, comme celle-ci et je n'ai trouvé aucune mention de cette bizarrerie. C'était la seule chose qui garantissait réellement que les fichiers étaient liés. Vérifier que le nombre de références était> 1 et que le nombre d'inodes était le même avecls -ilah
Walf
J'ai utilisé cela en conjonction avec la fonction relpath () décrite sur unix.stackexchange.com/a/85068/57414 pour sauvegarder un $SOURCErépertoire dans un répertoire $TARGETcomme celui-ci:SOURCE='abs_path_to_backup'; TARGET='.'; rsync -a --link-dest=$(relpath $TARGET $SOURCE) $SOURCE/ $TARGET/
Nathan S. Watson-Haigh
13

Ce que vous voulez, c'est "cp -al":

cp -al $DATA/ $DATA/../upgrade_tmp/
  • -une récurrente comme rsync -a
  • -l liera les fichiers en dur au lieu de les copier.
Sean Reifschneider
la source
1
cp -aln'est malheureusement pas disponible sur mon système (Mac OS X 10.6). Je vais utiliser pax à la place ...
Jean-Philippe Pellet
7

L' --link-destoption dans rsyncest relative au répertoire de destination , pas au répertoire courant. Donc ce que vous voulez c'est:

rsync -a --link-dest=../`basename $DATA` $DATA $DATA/../upgrade_tmp
Sean Reifschneider
la source
Oups, je voulais dire nom de base, à l'origine j'avais dirname.
Sean Reifschneider
1
La page de manuel indique que cette --link-destoption, si elle est relative , est relative au répertoire cible. Dans mon cas, c'est absolu. Même en le faisant par rapport au répertoire cible, cela ne fonctionne pas.
Jean-Philippe Pellet du
7

Il s'avère qu'il est plus difficile de le faire qu'avec rsyncd'autres outils. La bonne réponse rsyncest celle de Steven Monai, mais la façon la plus simple de le faire est d'utiliser soit cp -alou pax -rwlsur des systèmes où -ln'est pas une option valide pour cp:

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

ou

cp -al $DATA/ $DATA/../upgrade_tmp/
Jean-Philippe Pellet
la source
4

Ça marche pour moi:

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

J'utilise la version 3.1.0 de rsync.

De l' homme :

--hard-links

Indique à rsync de rechercher les fichiers liés en dur dans le transfert, sans cette option, les fichiers liés en dur dans le transfert sont traités comme s'il s'agissait de fichiers distincts.

--link-dest = DIR

Les fichiers inchangés sont liés de DIR au répertoire de destination. Les fichiers doivent être identiques dans tous les attributs préservés (par exemple les autorisations, éventuellement la propriété) pour que les fichiers soient liés ensemble

Alexander Fedorov
la source
2
Seul l'extrait de code ne suffit pas, expliquez ce qu'il fait et pourquoi.
peterh dit réintégrer Monica le
--hard-links Indique à rsync de rechercher les fichiers liés en dur dans le transfert, sans cette option, les fichiers liés en dur dans le transfert sont traités comme s'il s'agissait de fichiers distincts. --link-dest = DIR Les fichiers inchangés sont liés en dur de DIR au répertoire de destination. Les fichiers doivent être identiques dans tous les attributs préservés (par exemple les autorisations, éventuellement la propriété) pour que les fichiers soient liés ensemble.
Alexander Fedorov
1
Magnifique. Merci. En fait, j'ai trouvé votre réponse dans la file d'attente "de faible qualité". Cela signifie qu'il y a eu un vote si votre réponse devait être supprimée ou non. Mais non seulement le danger des suppressions est une raison pour essayer de donner une réponse "humaine" bien formatée, mais cela aide aussi beaucoup si vous voulez collecter des votes positifs.
Peterh dit de réintégrer Monica
2

Peut essayer le lien suivant http://www.lessfs.com/wordpress/ c'est un travail sur COW (copie sur écriture) qui fera gagner du temps et de l'espace

Rajat
la source
lessfs est très intéressant, mais aussi très expérimental. Pas encore recommandé pour une utilisation en production.
mattdm
2

Créez d'abord les répertoires uniquement sur la destination:

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

Reliez ensuite les fichiers en dur uniquement:

cd /source
find . -type f -exec ln -v {} /destination/{} \;
Cakemox
la source
Merci - en fait, je pourrais aussi bien utiliser paxcomme indiqué dans mon commentaire ci-dessus, ce qui semble plus facile.
Jean-Philippe Pellet
1

Utilisez l'option -H pour conserver les liens physiques et lire la page de manuel.

Texas
la source
1
-H ne fonctionne pas. Je n'ai aucun lien physique à conserver dans mon arborescence source, je veux juste une simple copie de mon arborescence source où dans la copie, tous les fichiers sont liés en dur aux fichiers originaux. Désolé dans ma question d'origine n'était pas claire…
Jean-Philippe Pellet
"lire la page de manuel" est-il une réponse? :-)
meduz