web-dev-qa-db-fra.com

rsync: --include-from vs. --exclude-from quelle est la différence réelle?

Dans la documentation, il les mentionne comme étant des fichiers contenant des listes de modèles à inclure ou de modèles à exclure. Cependant, cela implique pour les inclusions, tout est considéré comme une exclusion, sauf lorsque les choses correspondent aux modèles. Ainsi, par exemple, un fichier include contenant:

/opt/**.cfg

Ne doit inclure que n'importe quel fichier nommé * .cfg qui existe n'importe où sous un répertoire nommé opt n'importe où dans l'arborescence. Cela correspondrait donc à ce qui suit:

/opt/etc/myfile.cfg
/some/dir/opt/myfile.cfg
/notopt/opt/some/other/dir/myfile.cfg

Je m'attends donc à ce qu'il exclue implicitement toute autre chose. Mais cela ne semble pas être le cas, car je vois cela dans la sortie détaillée:

*deleting   etc/rc.d/init.d/somescript

Alors, quel est le problème avec --include-from et --exclude-from? S'agit-il simplement d'alias pour --filter-from?

25
Craig

rsync ne fonctionne pas comme ça. Tout fichier dont le modèle de nom de fichier ne correspond à aucun des modèles d'inclusion ou d'exclusion est considéré comme inclus. En d'autres termes, considérez le modèle d'inclusion comme un moyen de remplacer le modèle d'exclusion.

De la docs :

Rsync construit une liste ordonnée d'options d'inclusion/exclusion comme spécifié sur la ligne de commande. Rsync vérifie tour à tour chaque nom de fichier et de répertoire par rapport à chaque modèle d'exclusion/d'inclusion. Le premier motif correspondant est appliqué. S'il s'agit d'un motif d'exclusion, ce fichier est ignoré. S'il s'agit d'un modèle d'inclusion, ce nom de fichier n'est pas ignoré. Si aucun modèle d'inclusion/exclusion correspondant n'est trouvé, le nom de fichier n'est pas ignoré.

(Souligner le mien)

Donc, si vous souhaitez inclure uniquement des fichiers spécifiques, vous devez d'abord inclure ces fichiers spécifiques, puis exclure tous les autres fichiers:

--include="*/" --include="*.cfg" --exclude="*"

Quelques choses à noter ici:

  1. Les modèles include doivent précéder les exclus, car le premier modèle qui correspond est celui qui est pris en compte. Si le nom de fichier correspond d'abord au modèle d'exclusion, il est exclu.

  2. Vous devez soit inclure tous les sous-répertoires individuellement, comme --include="/opt" --include="/opt/dir1" etc. pour tous les sous-répertoires, ou utilisez --include = "* /" pour inclure tous les répertoires (pas les fichiers). Je suis allé avec la deuxième option par souci de concision.

C'est original et pas très intuitif. Alors lisez attentivement docs (la section "EXCLURE LES MOTIFS" du lien) et utilisez le --dry-run ou -n option pour vous assurer qu'il fera ce que vous pensez qu'il devrait faire.

81
Hari Menon

Si vous (comme moi) avez du mal à envelopper votre tête autour du FILTER RULES- dans les pages de manuel mais ayant une compréhension de base de find, vous pouvez l'utiliser à la place.

Supposons que vous souhaitiez synchroniser tout avec une date spécifique (ex 2016-02-01) dans le nom de fichier ou dans un nom de répertoire de /storage/data à rsync_test. Faites quelque chose comme ça:

cd /storage/data
find . -name '*2016-02-01*' \
  | rsync --dry-run -arv --files-from=- /storage/data /tmp/rsync_test
5
UlfR