12 votes

Comment puis-je synchroniser un ensemble de sous-répertoires avec rsync ?

J'ai un répertoire source qui ressemble à ce qui suit (avec de nombreux sous-répertoires à l'intérieur des dossiers src et bin) :

  • top_dir
    • proj1
      • src/
      • bin/
      • scripts/
      • somefile.txt
    • proj2
      • src/
      • bin/
      • target
        • bin/
      • file.xml

J'aimerais rsyncer seulement les dossiers bin directement sous les répertoires de projet (c'est-à-dire, ignorer top_dir/proj2/target/bin/) et leurs contenus vers le répertoire de destination, de sorte que cela ressemble à ceci :

  • top_dir
    • proj1
      • bin
    • proj2
      • bin

Je pourrais probablement y arriver en énumérant explicitement chaque répertoire bin (il y en a environ 15 dans mon scénario réel) dans un fichier include-from, mais je me disais qu'il devait y avoir un moyen de dire que je veux synchroniser tous les répertoires top_dir/*/bin.

21voto

mpy Points 24817

Possibilité 1

En utilisant l'expansion en coquillage1 au lieu des règles de filtre de rsync, vous pouvez faire comme suit :

a. Pour inclure tous les dossiers bin dans la hiérarchie du top_dir :

rsync -av -R top_dir/**/bin/ destination_path

Ici -R est un paramètre de rsync2 signifiant relatif. man rsync l'explique comme

Utiliser les chemins relatifs. Cela signifie que les noms de chemin complets spécifiés en ligne de commande sont envoyés vers le serveur plutôt que juste les dernières parties des noms de fichiers. C'est particulièrement utile lorsque vous voulez envoyer plusieurs répertoires différents en même temps.

mais en essence cela signifie que la structure des répertoires est préservée.

** est un motif de recherche shell et cherche de manière récursive des répertoires nommés bin sous top_dir. Ainsi, avec l'exemple ci-dessus, la ligne de commande est étendue à :

rsync -av -R top_dir/proj1/bin/ top_dir/proj2/bin/ destination_path

b. Si vous voulez seulement inclure les dossiers bin d'un seul niveau en dessous du répertoire du projet, utilisez simplement un seul * (cela fonctionne même avec les coquilles "antiques" !) :

rsync -av -R top_dir/*/bin/ destination_path

1 Vous avez besoin d'une version récente de bash (>4) et d'activer la recherche récursive via shopts -s globstar. Avec zsh la recherche récursive est activée par défaut.

2 rsync version v3.2.3, protocole version 31 sur Linux.

Possibilité 2

En n'utilisant que les règles de filtre de rsync, vous avez besoin de :

a. Pour inclure tous les dossiers bin dans la hiérarchie du top_dir :

rsync -av -m --include='**/' --include='**/bin/**' --exclude='*' top_dir/ destination_path

La première règle include pourrait ne pas être évidente3 mais garantit que tous les répertoires (notez le slash final /) sont recherchés, la seconde ajoute tout dans les répertoires bin, et la règle exclude exclut tout le reste. -m s'assure que les répertoires vides ne sont pas copiés.

b. Pour inclure seulement un niveau en dessous du répertoire du projet :

rsync -av -m --include='/*/' --include='/*/bin/***' --exclude='*' top_dir/ destination_path

En utilisant la syntaxe *** de rsync >= 2.6.7. Le slash initial / dans les motifs représentent top_dir, sinon les motifs sont comparés à la fin du chemin du fichier.


3 Recherchez /some/path/this-file-will-not-be-found dans man rsync

0voto

Griffin Points 1

Vous pouvez exclure tous les répertoires src en utilisant --exclude src/

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X