rsync certains files, à l'exclusion du rest, ignorant le directory .svn /, récursivement

J'utilise rsync pour copyr certains files d'un partage vers un autre.

Récursivement, j'ai besoin de:

  • Supprimer les files à destination qui ont été retirés de l'origine
  • Synchroniser uniquement les files php et js
  • Exclure tous les autres types de files
  • Ne pas supprimer les directorys .svn/ directory à destination

Si j'utilise ceci:

 rsync -zavC --delete --include='*.php' --include='*.js' --exclude="*" \ /origiin /destination 

Ensuite, rsync n'est pas récursif car exclude="*" exclut tous les files mais aussi les dossiers

Si j'ajoute --include="*/" alors le directory .svn/ est supprimé (il est également inclus)

Comment puis-je résoudre ce dilemme de dynamitage mentale?

uname -a :

Linux tux 3.9.2-1-ARCH # 1 SMP PREEMPT Sam May 11 20:31:08 CEST 2013 x86_64 GNU / Linux

Version de rsync :

 rsync 3.0.9-6 

1ère tentative (n'a pas fonctionné)

Vous devez inclure les directorys en plus des files:

 rsync -zavC --delete --include '*/' --include='*.php' --include='*.js' \ --exclude="*" /media/datacod/Test/ /home/lucas/Desktop/rsync/ 

2e tentative

 rsync -avzC --filter='-rs_*/.svn*' --include="*/" --include='*.js' \ --include='*.php' --exclude="*" --delete dir1/ dir2/ 

données de test

J'ai écrit ce script pour créer des exemples de données à tester. Voici ce script, setup_svn_sample.bash :

 #!/bin/bash # setup .svn dirs mkdir -p dir{1,2}/dir{1,2,3,4}/.svn # fake data under .svn mkdir -p dir1/dir{1,2,3,4}/.svn/origdir mkdir -p dir2/dir{1,2,3,4}/.svn/keepdir # files to not sync touch dir1/dir{1,2,3,4}/file{1,2} # files to sync touch dir1/dir{1,2,3,4}/file1.js touch dir1/dir{1,2,3,4}/file1.php 

En cours d'exécution, les directorys suivants sont générés:

source dir

 $ tree -a dir1 dir1 |-- dir1 | |-- file1 | |-- file1.js | |-- file1.php | |-- file2 | `-- .svn | `-- origdir |-- dir2 | |-- file1 | |-- file1.js | |-- file1.php | |-- file2 | `-- .svn | `-- origdir |-- dir3 | |-- file1 | |-- file1.js | |-- file1.php | |-- file2 | `-- .svn | `-- origdir `-- dir4 |-- file1 |-- file1.js |-- file1.php |-- file2 `-- .svn `-- origdir 

destination dir

 $ tree -a dir2 dir2 |-- dir1 | `-- .svn | `-- keepdir |-- dir2 | `-- .svn | `-- keepdir |-- dir3 | `-- .svn | `-- keepdir `-- dir4 `-- .svn `-- keepdir 

Exécutez la command rsync ci-dessus:

 rsync -avzC --filter='-rs_*/.svn*' --include="*/" --include='*.js' \ --include='*.php' --exclude="*" --delete dir1/ dir2/ sending incremental file list dir1/file1.js dir1/file1.php dir2/file1.js dir2/file1.php dir3/file1.js dir3/file1.php dir4/file1.js dir4/file1.php sent 480 bytes received 168 bytes 1296.00 bytes/sec total size is 0 speedup is 0.00 

Résultat de dir2 afterards:

 $ tree -a dir2 dir2 |-- dir1 | |-- file1.js | |-- file1.php | `-- .svn | `-- keepdir |-- dir2 | |-- file1.js | |-- file1.php | `-- .svn | `-- keepdir |-- dir3 | |-- file1.js | |-- file1.php | `-- .svn | `-- keepdir `-- dir4 |-- file1.js |-- file1.php `-- .svn `-- keepdir 

Pourquoi ça marche?

La pièce maîtresse de ce script est de faire usage de la capacité de filtrage de rsync . Les filters vous permettent de supprimer des files du jeu correspondant à différents points de la command. Donc, dans notre cas, nous filtrons les files qui correspondent au model */.svn* . Les modificateurs -rs_ indiquent au filter que nous voulons filterr à la fois du côté source et du côté cible.

extrait de la section FILTER NOTES de la page de manuel de rsync

  • Un s est utilisé pour indiquer que la règle s'applique au côté envoi. Lorsqu'une règle affecte le côté envoi, elle empêche les files d'être transférés. Par défaut, une règle affecte les deux côtés à less que --delete-excluded n'ait été spécifié, auquel cas les règles par défaut deviennent uniquement expéditeur. Voir aussi les règles hide (H) et show (S), qui sont une autre façon de spécifier les inclusions / exclusions côté envoi.

  • Un r est utilisé pour indiquer que la règle s'applique au côté récepteur. Lorsqu'une règle affecte le côté réception, elle empêche la suppression des files. Voir le modificateur s pour plus d'informations. Voir aussi les règles de protection (P) et de risque (R), qui sont une autre façon de spécifier les inclusions / exclusions côté récepteur.

Voir man rsync pour plus de détails.

Conseils pour comprendre ceci (indice en utilisant --dry-run )

En décrivant comment faire ceci, je pensais mentionner le --dry-run sur rsync . C'est extrêmement utile de voir ce qui se passera sans que le rsync réellement lieu.

Par exemple

L'utilisation de la command suivante fera un test et nous montrera la logique de décision derrière rsync :

 rsync --dry-run -avvzC --filter='-rs_*/.svn*' --include="*/" \ --include='*.js' --include='*.php' --exclude="*" --delete dir1/ dir2/ sending incremental file list [sender] showing directory dir3 because of pattern */ [sender] showing directory dir2 because of pattern */ [sender] showing directory dir4 because of pattern */ [sender] showing directory dir1 because of pattern */ [sender] hiding file dir1/file1 because of pattern * [sender] showing file dir1/file1.js because of pattern *.js [sender] hiding file dir1/file2 because of pattern * [sender] showing file dir1/file1.php because of pattern *.php [sender] hiding directory dir1/.svn because of pattern */.svn* [sender] hiding file dir2/file1 because of pattern * [sender] showing file dir2/file1.js because of pattern *.js [sender] hiding file dir2/file2 because of pattern * [sender] showing file dir2/file1.php because of pattern *.php [sender] hiding directory dir2/.svn because of pattern */.svn* [sender] hiding file dir3/file1 because of pattern * [sender] showing file dir3/file1.js because of pattern *.js [sender] hiding file dir3/file2 because of pattern * [sender] showing file dir3/file1.php because of pattern *.php [sender] hiding directory dir3/.svn because of pattern */.svn* [sender] hiding file dir4/file1 because of pattern * [sender] showing file dir4/file1.js because of pattern *.js [sender] hiding file dir4/file2 because of pattern * [sender] showing file dir4/file1.php because of pattern *.php [sender] hiding directory dir4/.svn because of pattern */.svn* delta-transmission disabled for local transfer or --whole-file [generator] risking directory dir3 because of pattern */ [generator] risking directory dir2 because of pattern */ [generator] risking directory dir4 because of pattern */ [generator] risking directory dir1 because of pattern */ [generator] protecting directory dir1/.svn because of pattern */.svn* dir1/file1.js dir1/file1.php [generator] protecting directory dir2/.svn because of pattern */.svn* dir2/file1.js dir2/file1.php [generator] protecting directory dir3/.svn because of pattern */.svn* dir3/file1.js dir3/file1.php [generator] protecting directory dir4/.svn because of pattern */.svn* dir4/file1.js dir4/file1.php total: matches=0 hash_hits=0 false_alarms=0 data=0 sent 231 bytes received 55 bytes 572.00 bytes/sec total size is 0 speedup is 0.00 (DRY RUN) 

Dans la sortie ci-dessus, vous pouvez voir que les directorys ./svn sont protégés par notre règle de filtrage. Un aperçu précieux pour déboguer le rsync .

Les references

  • Supprimer les files étrangers de dest dir via rsync?

Ok, après plusieurs essais, j'ai fait le sorting:

 rsync -vaiz --delete --exclude=.svn/ --include='*.php' --include='*.js' \ --include='*/' --exclude='*' --prune-empty-dirs \ --filter "protect .svn/" /origin /destination 

Je vous remercie