Beste Methode zum Synchronisieren von Dateien - Kopieren Sie nur vorhandene Dateien und nur, wenn diese NEUER als das Ziel sind

18

Ich mache diese Synchronisation lokal unter Ubuntu 12.04. Die Dateien sind in der Regel kleine Textdateien (Code).

Ich möchte mtime stamp aus dem sourceVerzeichnis in kopieren (beibehalten) , targetaber ich möchte nur kopieren, wenn die Datei in target bereits vorhanden und älter als die in ist source.

Ich kopiere also nur Dateien, die neueren Datums sind source, aber die müssen vorhanden targetsein, sonst werden sie nicht kopiert. ( sourcehat viel mehr Dateien als target.)

Ich werde tatsächlich sourcein mehrere targetVerzeichnisse kopieren . Ich erwähne dies für den Fall, dass sich dies auf die Wahl der Lösung auswirkt. Ich kann meinen Befehl jedoch problemlos mehrere Male ausführen und targetjedes Mal den neuen angeben, wenn dies erforderlich ist.

MountainX für Monica Cellio
quelle

Antworten:

29

Ich glaube, du kannst das gebrauchen rsync. Die Schlüsselbeobachtung wäre die Notwendigkeit, die Schalter --existingund zu verwenden --update.

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

Ein Befehl wie dieser würde es tun:

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

Beispiel

Angenommen, wir haben die folgenden Beispieldaten.

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

Welches sieht wie folgt aus:

$ 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

Wenn ich diese Verzeichnisse synchronisieren würde, würde nichts passieren:

$ 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

Wenn wir toucheine Quelldatei haben, damit sie neuer ist:

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

Eine weitere Ausführung des rsyncBefehls:

$ 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

Wir können sehen, dass es file3, da es neuer ist und darin existiert dst/, gesendet wird.

Testen

Um sicherzustellen, dass alles funktioniert, bevor Sie den Befehl loslassen, empfehle ich die Verwendung eines anderen rsyncSchalters von --dry-run. Fügen wir noch einen hinzu, -vdamit rsyncdie Ausgabe ausführlicher ist.

$ 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
quelle
Vielen Dank. Brauche ich nicht noch ein paar rsync-Optionen? Ich lese die Manpage. Scheint , wie ich dies benötigen: rsync --archive --update --existing --whole-file --itemize-changes a/ b. Oder sind die meisten dieser Optionen nicht erforderlich? (Ich habe die ganze Datei hinzugefügt, da es sich meistens um kleine Textdateien handelt.)
MountainX für Monica Cellio
@MountainX - füge nur die Optionen hinzu, die du brauchst. Ich würde damit anfangen, -adass eine Obermenge von Schaltern ist -rlptgoD.
SLM
Lassen Sie mich das klarstellen. Ich bin verwirrt über --updateund --existing. Brauche ich beides Ich habe Ihre Lösung getestet und es scheint zu funktionieren, aber ich fühle mich immer noch sicherer, wenn ich sie hinzufüge --update.
MountainX für Monica Cellio
@MountainX - sicher, dass Sie es hinzufügen können, ich werde es auch in das A setzen.
SLM