J'ai déjà copié des téraoctets de fichiers avec rsync
mais j'ai oublié d'utiliser --archive
pour conserver les attributs spéciaux des fichiers.
J'ai essayé d'exécuter rsync
encore cette fois avec --archive
mais c'était beaucoup plus lent que ce à quoi je m'attendais. Existe-t-il un moyen simple de procéder plus rapidement en copiant les métadonnées de manière récursive?
OK, vous pouvez copier le propriétaire, le groupe, les autorisations et l’horodatage à l’aide du paramètre --reference
dans chown
name__, chmod
name__, touch
name__. Voici un script pour le faire
#!/bin/bash
# Filename: cp-metadata
myecho=echo
src_path="$1"
dst_path="$2"
find "$src_path" |
while read src_file; do
dst_file="$dst_path${src_file#$src_path}"
$myecho chmod --reference="$src_file" "$dst_file"
$myecho chown --reference="$src_file" "$dst_file"
$myecho touch --reference="$src_file" "$dst_file"
done
Vous devriez l'exécuter avec Sudo
(pour autoriser le chown) et avec deux paramètres: le répertoire source et le répertoire de destination. Le script fait uniquement écho à ce qu'il ferait. Si cela vous convient, changez la ligne myecho=echo
avec myecho=
.
Traiter la question comme "rsync n'a que des métadonnées à copier, alors pourquoi est-ce si lent, et comment puis-je l'accélérer?":
rsync
utilise généralement des temps égaux comme heuristiques pour détecter et ignorer les fichiers non modifiés. Sans --archive
(en particulier, sans --times
), les heures du fichier de destination restent définies à l'heure à laquelle vous les avez synchronisées, tandis que les heures du fichier source restent intactes (sans vous tromper manuellement). Sans garantie extérieure de votre part que le contenu des fichiers source n'a pas changé, rsync doit en assumer le risque et doit donc les contrôler et/ou les copier à nouveau dans la destination. Ceci, ajouté au fait que --whole-file
est impliqué pour les synchronisations locales-> locales, rend rsync
sans --times
approximativement équivalent à cp
pour les synchronisations locales.
À condition que la mise à jour du contenu des fichiers de destination soit acceptable, ou si les fichiers source ne sont pas modifiés depuis la copie d'origine, vous devriez trouver rsync --archive --size-only
plus rapide qu'un rsync naïf.
En cas de doute quant à la copie de rsync
qui prend si longtemps, rsync --archive --dry-run --itemize-changes ...
vous indique de manière exhaustive, si concise, les détails.
AVERTISSEMENT: sans solution de contournement particulière, GNU cp --attributes-only
tronquera les fichiers de destination, au moins dans Precise. Voir l'édition ci-dessous.
Original:
Dans cette situation, vous voudrez probablement l'option GNU de --attributes-only
de cp, associée à --archive
, étant donné qu'il s'agit d'un code éprouvé, tous les attributs agnostiques de systèmes de fichiers ne suivent pas les liens symboliques (les suivre peut être mauvais!):
cp --archive --attributes-only /source/of/failed/backup/. /destination/
Comme avec les fichiers, cp
est additif avec les attributs étendus: si la source et la destination ont des attributs étendus, il ajoute les attributs étendus de la source à la destination (plutôt que de les supprimer). tous les xattrs de la destination en premier). Bien que cela reflète le comportement de cp
si vous copiez des fichiers dans une arborescence existante, il se peut que ce ne soit pas ce que vous attendiez.
Notez également que si vous n'avez pas conservé les liens physiques la première fois avec rsync
mais que vous voulez les conserver maintenant, alors cp
--- ne] corrige cela pour vous; vous feriez probablement mieux de relancer rsync
avec les bonnes options (voir mon autre réponse ) et d’être patient.
Si vous avez trouvé cette question en cherchant délibérément séparez et recombinez le contenu des métadonnées/fichiers, jetez un coup d'œil à metastore qui se trouve dans les dépôts Ubuntu.
Source: Manuel GNU coreutils
Édité pour ajouter:
cp
from GNU coreutils
name__> = 8.17 et supérieur fonctionnera comme décrit, mais coreutils <= 8.16 tronquera les fichiers lors de la restauration de leurs métadonnées. En cas de doute, n'utilisez pas cp
dans cette situation; utilisez rsync
with les bonnes options et/ou soyez patient.
Je ne le recommanderais pas à moins de bien comprendre ce que vous faites, mais il est possible d'empêcher GNU cp
de tronquer des fichiers à l'aide de l'astuce LD_PRELOAD :
/*
* File: no_trunc.c
* Author: D.J. Capelis with minor changes by Zak Wilcox
*
* Compile:
* gcc -fPIC -c -o no_trunc.o no_trunc.c
* gcc -shared -o no_trunc.so no_trunc.o -ldl
*
* Use:
* LD_PRELOAD="./no_trunc.so" cp --archive --attributes-only <src...> <dest>
*/
#define _GNU_SOURCE
#include <dlfcn.h>
#define _FCNTL_H
#include <bits/fcntl.h>
extern int errorno;
int (*_open)(const char *pathname, int flags, ...);
int (*_open64)(const char *pathname, int flags, ...);
int open(const char *pathname, int flags, mode_t mode) {
_open = (int (*)(const char *pathname, int flags, ...)) dlsym(RTLD_NEXT, "open");
flags &= ~(O_TRUNC);
return _open(pathname, flags, mode);
}
int open64(const char *pathname, int flags, mode_t mode) {
_open64 = (int (*)(const char *pathname, int flags, ...)) dlsym(RTLD_NEXT, "open64");
flags &= ~(O_TRUNC);
return _open64(pathname, flags, mode);
}
Dans les transferts locaux, lorsque la source et la destination se trouvent sur des systèmes de fichiers montés localement, rsync
copiera toujours le contenu de fichiers entiers. Pour éviter cela, vous pouvez utiliser
rsync -a --no-whole-file source dest
Je devais le faire à distance sur un autre ordinateur afin que je ne puisse pas utiliser - référence
J'ai utilisé cela pour faire le script ...
find -printf "touch -d \"%Tc\" \"%P\"\n" >/tmp/touch.sh
Mais assurez-vous qu'il n'y a pas de noms de fichiers avec "dans eux en premier ...".
find | grep '"'
Copiez ensuite touch.sh sur votre ordinateur distant et lancez ...
cd <DestinationFolder>; sh /tmp/touch.sh
Il existe également des options dans find -printf pour imprimer l'utilisateur et le nom du groupe si vous souhaitez les copier.