127 votes

Comment rsynchroniser uniquement une liste spécifique de fichiers ?

J'ai une cinquantaine de fichiers dans divers sous-répertoires que j'aimerais pousser vers un serveur distant. Je pensais que rsync pourrait le faire pour moi en utilisant l'option --include-from. Sans l'option --exclude="*", tous les fichiers du répertoire sont synchronisés, avec l'option, aucun fichier ne l'est.

rsync -avP -e ssh --include-from=deploy/rsync_include.txt --exclude=* ./ root@0.0.0.0:/var/www/ --dry-run

Je l'exécute en mode sec au départ et 0.0.0.0 est évidemment remplacé par l'IP du serveur distant. Le contenu de rsync_include.txt est une nouvelle liste de chemins relatifs aux fichiers que je veux télécharger, séparés par des lignes.

Y a-t-il une meilleure façon de procéder qui m'échappe en ce lundi matin ?

298voto

ash Points 6462

Il y a un drapeau --files-from qui fait exactement ce que vous voulez. De man rsync :

--files-from=FILE

L'utilisation de cette option vous permet de spécifier la liste exacte des fichiers à transférer (tels que lus depuis le FICHIER spécifié ou - pour l'entrée standard). Elle modifie également le comportement par défaut de rsync pour faciliter le transfert des fichiers et répertoires spécifiés :

  • L'option --relative (-R) est implicite, ce qui préserve les informations de chemin spécifiées pour chaque élément du fichier (utilisez --no-relative ou --no-R si vous voulez désactiver cette option).

  • L'option --dirs (-d) est implicite, ce qui créera les répertoires spécifiés dans la liste sur la destination plutôt que de les sauter bruyamment (utilisez --no-dirs ou --no-d si vous voulez désactiver cela).

  • Le comportement de l'option --archive (-a) n'implique pas --recursive (-r), donc spécifiez-la explicitement, si vous le souhaitez.

  • Ces effets secondaires modifient l'état par défaut de rsync, donc la position de l'option --files-from sur la ligne de commande n'a aucune incidence sur la façon dont les autres options sont analysées (par exemple, -a fonctionne de la même façon avant ou après --files-from, tout comme --no-R et toutes les autres options).

Les noms de fichiers qui sont lus à partir du FICHIER sont tous relatifs au répertoire source -- tout slash de tête est supprimé et aucune référence ".." n'est autorisée à aller plus haut que le répertoire source. Par exemple, prenez cette commande :

rsync -a --files-from=/tmp/foo /usr remote:/backup

Si /tmp/foo contient la chaîne "bin" (ou même "/bin"), le répertoire /usr/bin sera créé en tant que /backup/bin sur l'hôte distant. S'il contient "bin/" (notez le slash de fin de ligne), le contenu immédiat du répertoire sera également envoyé (sans avoir besoin d'être explicitement mentionné dans le fichier -- ceci a commencé dans la version 2.6.4). Dans les deux cas si l'option -r est activée, toute la hiérarchie de ce répertoire sera également transférée (gardez à l'esprit que -r doit être spécifié explicitement avec --files-from, puisqu'il n'est pas impliqué par -a). Notez également que l'effet de l'option --relative (activée par défaut) est de dupliquer uniquement l'information de chemin qui est lue à partir du fichier -- elle ne force pas la duplication de l'information de chemin. ne force pas la duplication du chemin de la spécification source (/usr dans ce cas).

En outre, le fichier --files-from peut être lu à partir de l'hôte distant au lieu de l'hôte local si vous spécifiez un " host : " devant le fichier (l'hôte doit correspondre à une extrémité du transfert). En raccourci, vous pouvez spécifier juste un préfixe " :" pour signifier "utiliser l'extrémité distante du transfert". Par exemple :

rsync -a --files-from=:/path/file-list src:/ /tmp/copy

Cela copierait tous les fichiers spécifiés dans le fichier /path/file-list qui se trouve sur l'hôte distant "src".

Si les options --iconv et --protect-args sont spécifiées et que les noms de fichiers --files-from sont envoyés d'un hôte à un autre, les noms de fichiers seront traduits du jeu de caractères de l'hôte émetteur au jeu de caractères de l'hôte récepteur.

NOTE : le tri de la liste des fichiers dans l'entrée --files-from aide rsync à être plus efficace, car il évitera de revisiter les éléments du chemin qui sont partagés entre des entrées adjacentes. Si l'entrée n'est pas triée, certains éléments du chemin (répertoires implicites) peuvent être analysés plusieurs fois, et rsync finira par les dédoubler après que après qu'ils aient été transformés en éléments de liste de fichiers.

15voto

K F Points 366

Pour mémoire, aucune des réponses ci-dessus ne m'a aidé, sauf une. Pour résumer, vous pouvez faire l'opération de sauvegarde en utilisant --files-from= en utilisant soit :

 rsync -aSvuc \`cat rsync-src-files\` /mnt/d/rsync\_test/

OU

 rsync -aSvuc --recursive --files-from=rsync-src-files . /mnt/d/rsync\_test/

La première commande est auto-explicative, à côté du contenu du fichier rsync-src-files que je vais développer ci-dessous. Maintenant, si vous voulez utiliser cette dernière version, vous devez garder à l'esprit les quatre remarques suivantes :

  1. Remarquez que vous devez spécifier à la fois --files-from y el source répertoire
  2. On doit spécifier explicitement --recursive .
  3. Le dossier rsync-src-files est un fichier créé par l'utilisateur et il a été placé dans le répertoire src pour ce test.
  4. Le site rsyn-src-files contiennent les fichiers et les dossiers à copier et ils sont pris relativement au répertoire source. IMPORTANT : Assurez-vous qu'il n'y a pas d'espaces de queue ou de lignes vides dans le fichier. Dans l'exemple ci-dessous, il n'y a que deux lignes, et non trois (Vous l'avez découvert par hasard). Contenu de rsynch-src-files es:

Nom du dossier1
Nom du dossier2

13voto

Waqas Khan Points 309

--files-from= doit être suivi d'une barre oblique si vous souhaitez conserver le chemin absolu intact. Ainsi votre commande deviendrait quelque chose comme ci-dessous :

rsync -av --files-from=/path/to/file / /tmp/

Cela peut être fait comme s'il y avait un grand nombre de fichiers et que vous vouliez copier tous les fichiers dans un chemin x. Vous trouverez donc les fichiers et enverrez la sortie dans un fichier comme ci-dessous :

find /var/* -name *.log > file

4voto

Victoria Stuart Points 21
$ date
  Wed 24 Apr 2019 09:54:53 AM PDT
$ rsync --version
  rsync  version 3.1.3  protocol version 31
  ...

Syntaxe : rsync <file_/_folder_list> <source> <target>

Dossier (ici, AVEC une terminaison / ; par exemple Cancer - Evolution/ ) sont dans un fichier de liste de dossiers (par exemple : cm_folder_list_test) :

# /mnt/Vancouver/projects/ie/claws/data/cm_folder_list_test
# test file: 2019-04-24
Cancer/
Cancer - Evolution/
Cancer - Genomic Variants/
Cancer - Metastasis (EMT Transition ...)/
Cancer Pathways, Networks/
Catabolism - Autophagy; Phagosomes; Mitophagy/
Catabolism - Lysosomes/

Si vous n'incluez pas ces extrémités / les dossiers cibles rsynchronisés sont créés, mais sont vides.

Ces noms de dossiers sont ajoutés au reste de leur chemin ( /home/victoria/Mail/2_RESEARCH - NEWS ), fournissant ainsi le chemin d'accès complet du dossier à rsync ; par exemple : /home/victoria/Mail/2_RESEARCH - NEWS/Cancer - Evolution/ .

Notez que vous devez également utiliser --files-from= ..., PAS --include-from= ...

rsync -aqP --delete --files-from=/mnt/Vancouver/projects/ie/claws/data/cm_folder_list_test "/home/victoria/Mail/2_RESEARCH - NEWS" $IN/

(Dans mon BASH script, j'ai défini la variable $IN comme suit :)

BASEDIR="/mnt/Vancouver/projects/ie/claws"
IN=$BASEDIR/data/test/input

Options rsync utilisées :

 -a  :   archive: equals -rlptgoD (no -H,-A,-X)
    -r  :   recursive
    -l  :   copy symlinks as symlinks
    -p  :   preserve permissions
    -t  :   preserve modification times 
    -g  :   preserve group 
    -o  :   preserve owner (super-user only) 
    -D  :   same as --devices --specials 
  -q  :   quiet (https://serverfault.com/questions/547106/run-totally-silent-rsync)

  --delete
    This  tells  rsync to delete extraneous files from the RECEIVING SIDE (ones
    that AREN’T ON THE SENDING SIDE), but only for the directories that are
    being synchronized.  You must have asked rsync to send the whole directory
    (e.g.  "dir" or "dir/") without using a wildcard for the directory’s contents
    (e.g. "dir/*") since the wildcard is expanded by the shell and rsync thus
    gets a request to transfer individual files, not the files’ parent directory.
    Files  that  are  excluded  from  the transfer are also excluded from being
    deleted unless you use the --delete-excluded option or mark the rules as
    only matching on the sending side (see the include/exclude modifiers in the
    FILTER RULES section).  ...

3voto

Wes Hardaker Points 10426

Edit : la réponse d'atp ci-dessous est meilleure. Veuillez utiliser celle-là !

Il vous sera peut-être plus facile, si vous recherchez une liste spécifique de fichiers, de les mettre directement dans la ligne de commande :

# rsync -avP -e ssh `cat deploy/rsync_include.txt` root@0.0.0.0:/var/www/

Cela suppose toutefois que votre liste n'est pas si longue que la longueur de la ligne de commande pose un problème et que la fonction rsync_include.txt ne contient que des chemins réels (c'est-à-dire pas de commentaires, ni de regexps).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X