Comment copier des répertoires en préservant les liens durs?

40

Comment déplacer des répertoires qui ont des fichiers en commun d'une partition à une autre?

Supposons que nous ayons une partition montée sur /mnt/Xdes répertoires partageant des fichiers avec des liens physiques. Comment déplacer de tels répertoires vers une autre partition, que ce soit /mnt/Yavec la préservation de ces liens en dur.

Pour mieux illustrer ce que je veux dire par "répertoires partageant des fichiers en commun avec des liens durs", voici un exemple:

# let's create three of directories and files
mkdir -p a/{b,c,d}/{x,y,z}
touch a/{b,c,d}/{x,y,z}/f{1,2,3,4,5}
# and copy it with hardlinks
cp -r -l a hardlinks_of_a

Pour être plus précis, supposons que la taille totale des fichiers soit de 10 Go et que chaque fichier comporte 10 liens physiques. La question est de savoir comment le déplacer vers une destination avec l’utilisation de la 10G (quelqu'un pourrait dire à propos de la copie avec 100G puis de la déduplication - ce n’est pas ce que je demande).

Grzegorz Wierzowiecki
la source

Réponses:

29

Première réponse: la méthode GNU

Les cp -acopies GNU préservent récursivement autant de structures et de métadonnées que possible. Les liens physiques entre les fichiers du répertoire source sont inclus dans cela. Pour sélectionner la préservation de liaison physique spécifiquement sans toutes les autres fonctionnalités de -a, utilisez --preserve=links.

mkdir src
cd src
mkdir -p a/{b,c,d}/{x,y,z}
touch a/{b,c,d}/{x,y,z}/f{1,2,3,4,5}
cp -r -l a hardlinks_of_a
cd ..
cp -a src dst
Alan Curry
la source
3
+1 sur tar, -1 pour l'utilisation d'arguments spécifiques à gnu pour cp.
WhyNotHugo
Vous avez donné trois réponses en une. Pourriez-vous les diviser en trois afin qu'ils puissent être commentés et évalués séparément? (Astuce: vous pouvez modifier ceci, pour n'en laisser qu'un - par exemple "cp -a". Ajoutez-en deux autres, pour "tar" et "pax")
Grzegorz Wierzowiecki le
1
@GrzegorzWierzowiecki split accompli
Alan Curry le
6
@ Hugo: il n'y a rien de mal à utiliser des arguments spécifiques à GNU avec des outils standard. Les versions GNU sont la norme de facto de nos jours, et même lorsqu'elles n'étaient pas préinstallées, il était courant d'installer des outils GNU (je sais que je l'ai toujours fait - ils étaient simplement meilleurs que, par exemple, les versions solaris et * bsd , et ils ont fourni une cohérence entre * nixes différents). C'est probablement une bonne pratique de signaler les GNUismes quand vous les utilisez, mais pas obligatoire. De plus, Grzegorz n'a pas dit "not on linux", il est donc raisonnable de supposer que c'est l'environnement dont il parle.
cas le
1
@WhyNotHugo: Comment POSIX "peut-il être plus standard?". POSIX est ce qui nous a amené là où nous sommes. Saviez-vous que toutes les versions de Windows depuis Windows NT sont entièrement compatibles POSIX? Leur longueur de chemin est limitée à 255 caractères lors de l’utilisation des fonctions d’E / S sur fichier POSIX, ce qui les rend inutiles. Saviez-vous que Solaris, Irix et HP-UX sont tous conformes à POSIX, et pourtant, tous les arguments de leurs outils diffèrent (par exemple, tar). cp -a est une exigence minimale pour toute version de cp qui souhaite remplacer la copie GNU.
Johannes Overmann
37

rsync a une option -Hou --hard-linkspour cela, et présente les avantages habituels de pouvoir être arrêté, redémarré et ré-exécuté pour traiter efficacement tous les fichiers modifiés pendant / après l’exécution précédente.

-H, --hard-links
    This tells rsync to look for hard-linked files in
    the source and link together the corresponding
    files on the destination.  Without  this option,
    hard-linked files in the source are treated as
    though they were separate files. [...]

Lisez la rsyncpage de manuel et recherchez -H. Il y a beaucoup plus de détails à ce sujet concernant certaines mises en garde.

cas
la source
2
J'ai vérifié - ça marche.
Grzegorz Wierzowiecki
Oui, je sais. Je l'utilise depuis des années dans mes scripts de sauvegarde. également pour déplacer des fichiers entre les systèmes de fichiers, comme dans votre question.
cas le
rsync utilise des gobs de mémoire lors de la construction de sa liste de fichiers. Pour moi, après de nombreuses heures de "liste de fichiers de construction ...", il a rempli mes 16 Go de mémoire et s'est sauvé sans rien copier. YMMV.
msc
2
Depuis man rsync: à compter de rsync 3.0.0, l'algorithme récursif utilisé est désormais une analyse incrémentielle utilisant beaucoup moins de mémoire qu'auparavant et commençant le transfert une fois l'analyse des quelques premiers répertoires terminée. Cette analyse incrémentielle n'affecte que notre algorithme de récursivité et ne modifie pas un transfert non récursif. Cela n'est également possible que lorsque les deux extrémités du transfert sont au moins à la version 3.0.0. Notez que tous les deux --delete-beforeet --delete-afterdésactivez cet algorithme amélioré.
cas
En outre, bien qu’il rsyncsoit incroyablement utile aussi, il n’est pas toujours le meilleur outil pour chaque travail. Ces jours-ci, je préfère utiliser les ensembles de données ZFS pour pouvoir prendre des clichés instantanés zfs send. J'utilise principalement rsync sur des systèmes de fichiers non-ZFS. btrfsa une capacité similaire d'instantané + envoi.
cas
14

Troisième réponse: la manière POSIX

POSIX n'a ​​pas normalisé l' tarutilitaire, bien qu'il ait normalisé le tarformat d'archive. L'utilitaire POSIX permettant de manipuler des archives tar est appelé pax. Il présente également l'avantage de pouvoir effectuer l'opération de décompression et de décompression en un seul processus.

mkdir dst
pax -rw src dst
Alan Curry
la source
10

Deuxième réponse: l'ancienne manière UNIX

Créez une archive tar dans le répertoire source, envoyez-la par un canal et décompressez-la dans le répertoire de destination.

# create src as before
(cd src;tar cf - .) | (mkdir dst;cd dst;tar xf -)
Alan Curry
la source
1
vérifié -> fonctionne. Les liens durs sont préservés.
Grzegorz Wierzowiecki
1
Avez-vous une idée de la raison pour laquelle cela préserve réellement les liens durs?
Peter
1
Parce que tarpréserve les liens durs. Dans GNU tar, vous pouvez au moins désactiver ce comportement avec--hard-dereference
cas le
Dans mon cas, en essayant de copier une hiérarchie de répertoires volumineuse (une sauvegarde TimeMachine), tar préservait certains liens physiques mais répliquait le fichier dans certains cas. Je pense que cela est dû au tar xfait que le ne possède pas la liste complète des fichiers, car les fichiers sont toujours acheminés depuis le tar c. Probablement, si vous avez sauvegardé l'intégralité de l'archive avant de l'extraire, tout ira bien. Je serais très heureux si quelqu'un pouvait confirmer cette théorie.
msc
10

Source: http://www.cyberciti.biz/faq/linux-unix-apple-osx-bsd-rsync-copy-hard-links/

Ce dont vous avez besoin pour faire une copie exacte, c'est

rsync -az -H --delete --numeric-ids /path/to/source/ /path/to/dest/
Pykler
la source
Voir mon commentaire sur rsync ci-dessus.
msc
1
Je soupçonne que cela ne copiera pas les ACL, les attributs étendus, etc. La version Linux a aussi les options -A et -X pour les conserver, mais je pense que vous n’avez pas de chance avec MacOS.
Edward Falk