Il modo migliore per sincronizzare i file: copia solo i file ESISTENTI e solo se PIÙ NUOVO del target


18

Sto eseguendo questa sincronizzazione localmente su Ubuntu 12.04. I file sono generalmente piccoli file di testo (codice).

Voglio copiare (preservando il timbro mtime) dalla sourcedirectory targetma voglio solo copiarlo se il file è target già esistente ed è più vecchio di quello in source.

Quindi sto solo copiando i file più recenti source, ma devono esistere targeto non verranno copiati. ( sourceavrà molti più file di target.)

In realtà copierò da sourcepiù targetdirectory. Ne parlo nel caso in cui influisca sulla scelta della soluzione. Tuttavia, posso facilmente eseguire il mio comando più volte, specificando targetogni volta il nuovo , se è quello che è richiesto.

Risposte:


29

Credo che tu possa usare rsyncper fare questo. L'osservazione chiave sarebbe nel bisogno di usare gli switch --existinge --update.

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

Un comando come questo lo farebbe:

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

Esempio

Supponiamo di avere i seguenti dati di esempio.

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

Che ha il seguente aspetto:

$ 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

Ora se dovessi sincronizzare queste directory non accadrebbe nulla:

$ 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

Se abbiamo touchun file sorgente in modo che sia più recente:

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

Un'altra esecuzione del rsynccomando:

$ 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

Possiamo vedere che file3, poiché è più recente e in cui esiste dst/, viene inviato.

analisi

Per assicurarsi che il lavoro le cose prima di tagliare il comando sciolto, io suggerirei di usare un altro di rsyncinterruttori 's, --dry-run. Aggiungiamo -vanche un altro così rsyncl'output è più dettagliato.

$ 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)

Grazie. Non ho bisogno di qualche altra opzione rsync? Sto leggendo la pagina man. Sembra che potrei aver bisogno questo: rsync --archive --update --existing --whole-file --itemize-changes a/ b. O la maggior parte di queste opzioni non sono necessarie? (Ho aggiunto l'intero file perché si tratta per lo più di piccoli file di testo.)
MountainX per Monica Cellio

@MountainX: aggiungi solo le opzioni che ti servono. Mi piacerebbe iniziare con -aquesto è un superset di interruttori, -rlptgoD.
slm

Vorrei chiarirlo. Sono confuso su --updatee --existing. Ho bisogno di entrambi? Ho testato la tua soluzione e sembra funzionare, ma mi sento ancora più sicuro --update.
MountainX per Monica Cellio,

@MountainX - sicuro che puoi aggiungerlo, lo inserirò anche nella A.
slm
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.