Rsync: Kopieren nur über Zeitstempel

42

Derzeit habe ich zwei Verzeichnisse A / und B /, die bis auf die Zeitstempel in jeder Hinsicht identisch sind. Daher, wenn ich den Befehl ausführen:

rsync --dry-run -crvv A/ B/

dann sind alle Dateien mit "uptodate" markiert, während der Befehl:

rsync --dry-run -rvv A/ B/

zeigt an, dass alle Dateien von A / nach B / kopiert werden sollen.

Meine Frage lautet: Wenn ich weiß, dass die Dateien (in Bezug auf den Inhalt) identisch sind, gibt es dann eine Möglichkeit (über rsync oder auf andere Weise), die Zeitstempel für Dateien in B / so festzulegen, dass sie mit den Zeitstempeln der Dateien in identisch sind A /, ohne alle Dateien von A / nach B / zu kopieren?

Vielen Dank

artella
quelle
Wenn Sie wissen, dass die Dateien identisch sind, warum müssen Sie sich dann Mühe geben, sie nicht zu kopieren, um den gewünschten Datums- / Zeitstempel zu erhalten?
Tim
3
@ Tim: Vielleicht gibt es eine Menge Daten.
Richard

Antworten:

75

Wenn Sie -t(Zeitstempel beibehalten) verwenden, --size-onlywerden die Dateien nur nach Größe verglichen. Wenn die Größe übereinstimmt, kopiert rsync die Datei nicht. Da -tjedoch angegeben ist, wird der Zeitstempel in der Zieldatei aktualisiert, ohne sie erneut zu kopieren.

Stellen Sie sicher, dass Sie -u(update) nicht verwenden, da hierdurch bereits vorhandene Dateien und die Aktualisierung des Zeitstempels vollständig übersprungen werden.

Ich hatte das Problem, ursprünglich nicht mit rsync eine Reihe von Dateien auf ein neues Laufwerk zu kopieren, und daher wurden die Zeitstempel auf die aktuelle Zeit aktualisiert. Ich habe den folgenden Befehl verwendet, um alles in angemessener Zeit korrekt zu synchronisieren:

rsync -vrt --size-only /src /dest
Grant Pannell
quelle
2
Ich empfehle auch das Hinzufügen --existing, um versehentliche Kopien neuer Dateien zu verhindern.
Leden
1
Das Flag --archive(oder -a) umfasst -r, -tund mehr :)
Dor
6

Die Verwendung von --size-only führt dazu, dass rsync den Vergleich von Dateizeitstempeln (und damit des Dateiinhalts) überspringt, wenn die Größen übereinstimmen. Wenn Sie dies mit --times kombinieren, werden die Zeitstempel in den Zielbaum geklont.

user115916
quelle
3

Ich denke, rsync ist das richtige Werkzeug, um dies zu tun, aber wenn Sie ein Skript benötigen, um dies zu tun, kann dies einen guten Anfang geben.

Sie können eine Dateiliste mit Zeitstempeln (Zugriffszeiten) wie folgt erhalten:

find . -printf '"%p" %a\n' -type f > /tmp/times

Und holen Sie sich die entsprechenden Zeitaktualisierungsbefehle:

 while read line; do echo touch -a -d \"${line#* }\" ${line%% *}; done < /tmp/times

Es ist kein vollständiges Skript, aber ein guter Startpunkt! :)

Stein
quelle
Vielen Dank. Ich denke, ich werde wahrscheinlich für den Moment bei Rsync bleiben, aber ich werde definitiv ins Internet gehen und die verschiedenen Komponenten Ihres Skripts lernen, da dies in Zukunft nützlich sein könnte.
Artella
Das schien genau meine Lösung zu sein! Ich möchte die Zeiten bewahren, während ich meiner Musikbibliothek einige Metadaten hinzufüge. Allerdings kann es anscheinend keine Leerzeichen in Dateinamen verarbeiten):
Burcardo
2

Verwenden Sie das Quellverzeichnis (z. B. /path/to/source) als Referenz für den Touch-Befehl. Einfach cdin dein Zielverzeichnis und fertig

find -type f -exec touch -r /path/to/source/{} {} \;

Mit rsync können (noch) keine Zeitstempel unter einer Sekunde kopiert werden.

Dies funktioniert auch für Verzeichnisse und Pseudodateien (einfach entfernen oder ändern -type f)

knorke
quelle
Dies war nützlich für mich, da ich Zeit brauchte, um kopiert zu werden. Mir ist aufgefallen, dass es keine Uhrzeit kopiert, was in meinem Fall in Ordnung war.
Snapfractalpop
Lies einfach die Manpage von 'touch'. Mit diesem Befehl können Sie sowohl atime als auch mtime einstellen.
Knorke
Ja, ich weiß, dass Sie verwenden können, touch -araber das ändert immer noch nichts an der Uhrzeit. Ich nehme an, das ist selten erwünscht.
Snapfractalpop
Ah, ich sehe das Problem jetzt. Vielen Dank. Ja, die Uhrzeit ist schwer zu ändern und ich weiß nicht warum.
Knorke
1

Nun, Sie könnten sicherlich ein Skript schreiben, das den Zeitstempel von einer Seite liest und ihn dann mit touch auf dieselbe Datei auf der anderen Seite legt.

Aber das würde wahrscheinlich viel länger dauern, als rsync einfach versuchen zu lassen, alle Dateien zu kopieren. Tatsächlich werden nur sehr wenige Daten übertragen (nur Block-Hashes, wenn die Dateien wirklich identisch sind). Der vollständige Inhalt jeder Datei muss jedoch mindestens auf jeder Seite gelesen werden. Sie sind also aufgrund der Festplattenbandbreite oder des IOPS begrenzt, was eine Weile dauern kann. Aber immer noch wahrscheinlich weniger Zeit als das Schreiben und Testen eines Skripts, um es zu tun.

Malayter
quelle
Vielen Dank, mir war diese Funktion von rsync nicht bekannt (sie wird auch in Wikipedia behandelt).
Artella
0

Für Leute wie mich, die beabsichtigen, die Dateien zu ändern und den ursprünglichen Zeitstempel beizubehalten (z. B. Sie aktualisieren die Meta-Tags Ihrer Musikbibliothek).

Es basiert auf der Lösung von Stone. Allerdings hier über die Änderungszeit und ein funktionierendes Skript zur Wiederherstellung der Zeitstempel. ZUERST mache Schritt eins und beginne dann mit deinen Dateien zu arbeiten.

  1. Alte Zeitstempel beibehalten . Es wird aus dem aktuellen Verzeichnis ausgeführt, schließt alle versteckten Dateien aus und speichert sie in der temporären Datei in /tmp/files. Sie können die Parameter jederzeit ändern, aber bleiben Sie besser dabei, -printf '"%t" "%p"\n'da der spätere touchBefehl dies nutzt.

    find . ! -iname ".*" -printf '"%t" "%p"\n' -type f > /tmp/files

  2. Ändern Sie Ihre Dateien nach Belieben

  3. Erstellen Sie jetzt eine Datei, mit der Sie die Zeitstempel wiederherstellen können:

    while read line; do echo touch -a -d $line >> job.sh; done < /tmp/times

  4. Und schließlich wenden Sie die alten Daten auf die geänderten Dateien an

    sh job.sh

Vorsichtsmaßnahme: Funktioniert für Dateien mit Namensabstand, Sonderzeichen, aber zum Beispiel keine Dateien mit einem $Zeichen.

Burcardo
quelle
Um (einige) Probleme mit Backslashes in Ihren Dateinamen zu vermeiden, verwenden Sie read -r line. Nun, immer verwenden readmit -r. Außerdem können Sie das Öffnen job.shfür jede Datei vermeiden . while read -r path; do echo touch -a -d $path ; done < /tmp/times > job.sh
Fügen Sie
2. Warnung: Dieses Skript überträgt nicht die Zeitstempel der Verzeichnisse. (Nun, das OP hat nicht darum
gebeten
0

So kopieren Sie nur den Zeitstempel unter Windows:

Um den zuletzt erstellten / geänderten / aufgerufenen Zeitstempel einer Datei in eine andere zu kopieren, können Sie Folgendes verwenden:

Berühren Sie / c / m / a / r SourceFile DestFile

(Diese Version von Touch ist Teil der Win32 Console ToolBox http://www.stevemiller.net/apps/ )

Robocopy "SOURCE_DIRECTORY" "DESTINATION_DIRECTORY" / E / COPYALL / DCOPY: DAT / XF . / R: 10 / W: 5 / V / ETA

Pierre
quelle
-1

Das rsync-Handbuch: man rsynclistet a -tund -Nswitch auf, mit denen es sich möglicherweise zu experimentieren lohnt.

Tim
quelle
Ich konnte nicht sehen -N. Warum empfehlen Sie diese überhaupt?
Tom Hale