Meilleure façon de synchroniser les fichiers - copiez uniquement les fichiers EXISTANTS et uniquement s'ils sont PLUS RÉCENTS que la cible

18

Je fais cette synchronisation localement sur Ubuntu 12.04. Les fichiers sont généralement de petits fichiers texte (code).

Je veux copier (en préservant le tampon mtime) du sourcerépertoire vers targetmais je ne veux copier que si le fichier dans target existe déjà et est plus ancien que celui dans source.

Je ne copie donc que des fichiers plus récents source, mais ils doivent exister targetou ils ne seront pas copiés. ( sourceaura beaucoup plus de fichiers que target.)

Je vais en fait copier à partir sourcede plusieurs targetrépertoires. Je le mentionne au cas où cela aurait un impact sur le choix de la solution. Cependant, je peux facilement exécuter ma commande plusieurs fois, en spécifiant la nouvelle à targetchaque fois, si c'est ce qui est requis.

MountainX pour Monica Cellio
la source

Réponses:

29

Je pense que vous pouvez l'utiliser rsyncpour cela. L'observation clé serait de devoir utiliser les commutateurs --existinget --update.

        --existing              skip creating new files on receiver
        -u, --update            skip files that are newer on the receiver

Une commande comme celle-ci le ferait:

$ rsync -avz --update --existing src/ dst

Exemple

Disons que nous avons les exemples de données suivants.

$ mkdir -p src/; touch src/file{1..3}
$ mkdir -p dst/; touch dst/file{2..3}
$ touch -d 20120101 src/file2

Qui ressemble à ceci:

$ ls -l src/ dst/
dst/:
total 0
-rw-rw-r--. 1 saml saml 0 Feb 27 01:00 file2
-rw-rw-r--. 1 saml saml 0 Feb 27 01:00 file3

src/:
total 0
-rw-rw-r--. 1 saml saml 0 Feb 27 01:00 file1
-rw-rw-r--. 1 saml saml 0 Jan  1  2012 file2
-rw-rw-r--. 1 saml saml 0 Feb 27 01:00 file3

Maintenant, si je synchronisais ces répertoires, rien ne se passerait:

$ rsync -avz --update --existing src/ dst
sending incremental file list

sent 12 bytes  received 31 bytes  406.00 bytes/sec
total size is 0  speedup is 0.00

Si nous avons touchun fichier source pour qu'il soit plus récent:

$ touch src/file3 
$ ls -l src/file3
-rw-rw-r--. 1 saml saml 0 Feb 27 01:04 src/file3

Une autre exécution de la rsynccommande:

$ rsync -avz --update --existing src/ dst
sending incremental file list
file3

sent 115 bytes  received 31 bytes  292.00 bytes/sec
total size is 0  speedup is 0.00

Nous pouvons voir que file3, puisqu'il est plus récent et qu'il existe dst/, il est envoyé.

Essai

Pour faire fonctionner que les choses avant de vous couper , je vous suggère la commande lâche, en utilisant un autre des rsynccommutateurs de », --dry-run. Ajoutons-en un autre -vaussi, donc rsyncla sortie est plus détaillée.

$ rsync -avvz --dry-run --update --existing src/ dst 
sending incremental file list
delta-transmission disabled for local transfer or --whole-file
file1
file2 is uptodate
file3 is newer
total: matches=0  hash_hits=0  false_alarms=0 data=0

sent 88 bytes  received 21 bytes  218.00 bytes/sec
total size is 0  speedup is 0.00 (DRY RUN)
slm
la source
Je vous remercie. N'ai-je pas besoin de quelques options rsync supplémentaires? Je lis la page de manuel. On dirait que je pourrais avoir besoin ceci: rsync --archive --update --existing --whole-file --itemize-changes a/ b. Ou la plupart de ces options sont-elles inutiles? (J'ai ajouté un fichier entier car il s'agit principalement de petits fichiers texte.)
MountainX pour Monica Cellio
@MountainX - ajoutez uniquement les options dont vous avez besoin. Je commencerai par -ac'est un surensemble de commutateurs, -rlptgoD.
slm
Permettez-moi de clarifier cela. Je suis confus au sujet de --updateet --existing. Ai-je besoin des deux? J'ai testé votre solution et elle semble fonctionner, mais je me sens toujours plus en sécurité --update.
MountainX pour Monica Cellio
@MountainX - bien sûr que vous pouvez l'ajouter, je le mettrai aussi dans le A.
slm