Wie synchronisiere ich zwei Ordner mit Kommandozeilen-Tools?


63

Nachdem ich von Windows auf Linux migriert bin, möchte ich eine alternative Software zu Winmerge finden oder Befehlszeilentools zum Vergleichen und Synchronisieren von zwei Ordnern unter Linux erlernen. Ich wäre Ihnen dankbar, wenn Sie mir sagen könnten, wie die folgenden Aufgaben in der Befehlszeile auszuführen sind ... (Ich habe diff und rsync studiert, benötige aber noch Hilfe.)

Wir haben zwei Ordner: "/ home / user / A" und "/ home / user / B"

Ordner A ist der Ort, an dem normale Dateien und Ordner gespeichert werden, und Ordner B ist ein Sicherungsordner, der als vollständiger Spiegel von Ordner A dient. (Nichts wird direkt vom Benutzer in Ordner B gespeichert oder geändert.)

Meine Fragen sind:

  • Wie liste ich Dateien auf, die nur in Ordner B existieren? (ZB diejenigen, die seit der letzten Synchronisierung aus Ordner A gelöscht wurden.)

  • Wie kopiere ich Dateien, die nur in Ordner B existieren, zurück in Ordner A?

  • Wie liste ich Dateien auf, die in beiden Ordnern vorhanden sind, aber unterschiedliche Zeitstempel oder Größen haben? (Diejenigen, die in Ordner A seit der letzten Synchronisierung geändert wurden. Ich möchte die Verwendung von Prüfsummen vermeiden, da es Zehntausende von Dateien gibt und dies den Prozess zu langsam machen würde.)

  • Wie erstelle ich eine exakte Kopie von Ordner A in Ordner B? Ich meine, kopiere alles von Ordner A in Ordner B, der nur in Ordner A existiert, und lösche alles von Ordner B, der nur in Ordner B existiert, ohne jedoch die Dateien zu berühren, die in beiden Ordnern gleich sind.


Warum nicht ein geeignetes Sicherungsprogramm verwenden? Duplizität ist ein Beispiel.
Qudit

Antworten:


88

Dadurch wird Ordner A in Ordner B verschoben:

rsync -avu --delete "/home/user/A" "/home/user/B"  

Wenn der Inhalt der Ordner A und B identisch sein soll, geben Sie /home/user/A/(mit dem Schrägstrich) als Quelle an. Dies nimmt nicht den Ordner A, sondern den gesamten Inhalt und legt ihn in Ordner B ab.

rsync -avu --delete "/home/user/A/" "/home/user/B"
  • -a Führen Sie die Synchronisierung unter Beibehaltung aller Dateisystemattribute durch
  • -v wortreich laufen
  • -u Kopieren Sie nur Dateien mit einer neueren Änderungszeit (oder einem Größenunterschied, wenn die Zeiten gleich sind).
  • --delete Löschen Sie die Dateien im Zielordner, die in der Quelle nicht vorhanden sind

Manpage: https://download.samba.org/pub/rsync/rsync.html


7
rsync : Führen Sie die rsync-App aus. -a : Führen Sie die Synchronisierung unter Beibehaltung aller Dateisystemattribute aus. -v : Führen Sie sie ausführlich aus. -z : Komprimieren Sie die Daten während der Synchronisierung (transportieren Sie die Daten im komprimierten Modus). --delete : Löschen Sie die Dateien im Ziel Ordner, die nicht in der Quelle existieren / home / user / A : Quellordner, / home / user / B : Zielordner
SonicARG

Hallo SonicARG, ich habe völlig vergessen, darauf zurückzukommen und die Erklärung einzutragen, danke, dass ich die Erklärung eingereicht habe.
TuxForLife

6
Rsync ist in erster Linie dazu gedacht, Dateien zwischen verschiedenen Computern zu kopieren. Wie hier erläutert, kann es auch dazu dienen, Verzeichnisse zu synchronisieren. Daher ist die Option -z interessant, um den Netzwerkverkehr zu reduzieren und damit die Leistung einer Synchronisierung zwischen zwei Computern zu verbessern: (Daten von der Festplatte lesen -> komprimieren) === Netzwerk ===> (dekomprimieren-> auf die Festplatte schreiben) Verwenden von - z zu synchronisieren 2 Verzeichnisse auf dem gleichen Host ist ein bisschen albern und Verschwendung von CPU-Zyklen, wie Sie bekommen würden (Daten von der Festplatte lesen -> komprimieren -> dekomprimieren -> auf die Festplatte schreiben)
GerritCap

@ GerritCap, ich habe eine Bearbeitung vorgenommen, danke für Ihre wertvolle Eingabe
TuxForLife

1
Ich habe den Befehl ausprobiert, aber er erstellt ein Unterverzeichnis, /home/user/B/Aanstatt den Inhalt von A mit dem Inhalt von B zu überschreiben. Könnten Sie mir helfen, einen Blick darauf zu werfen?
Luke

10

Sie könnten unisonvon Benjamin Pierce bei U Penn entwickeltes Werkzeug.

Nehmen wir an, Sie haben zwei Verzeichnisse,

/home/user/Documents/dirA/ und /home/user/Documents/dirB/

Um diese beiden zu synchronisieren, können Sie Folgendes verwenden:

~ $unison -ui text /home/user/Documents/dirA/ /home/user/Documents/dirB/

In der Ausgabe unisonwerden alle Verzeichnisse und Dateien angezeigt, die sich in den beiden zu synchronisierenden Verzeichnissen unterscheiden . Es wird empfohlen additiv synchronisieren (replizieren Datei in beiden Orten fehlen) auf dem Vorlauf, dann erstellen und einen Synchronisationsbaum auf Ihrem Rechner zu halten und auf dem folgenden Durchläufen wird es echte Synchronisation (dh implementieren, wenn Sie aus einer Datei löschen .../dirA, es wird aus gelöscht werden , .../dirBwie gut. Sie können auch jede Änderung vergleichen und gegebenenfalls wählen vorwärts oder umgekehrt zwischen den beiden Verzeichnisse synchronisieren.

Optional können Sie zum Starten der grafischen Benutzeroberfläche einfach die -ui textOption aus Ihrem Befehl entfernen , obwohl ich die clieinfachere und schnellere Verwendung finde .

Mehr dazu: Unison-Tutorial in der Unison-Benutzerdokumentation .


1

Die Antwort von TuxForLife ist ziemlich gut, aber ich empfehle dringend, sie -cbeim lokalen Synchronisieren zu verwenden. Sie können argumentieren, dass es nicht die Zeit- / Netzwerkstrafe wert ist, dies für Remote-Synchronisierungen zu tun, aber es lohnt sich absolut für lokale Dateien, da die Geschwindigkeit so groß ist.

-c, --checksum
       This forces the sender to checksum every regular file using a 128-bit  MD4
       checksum.   It  does this during the initial file-system scan as it builds
       the list of all available files. The receiver then checksums  its  version
       of  each  file  (if  it exists and it has the same size as its sender-side
       counterpart) in order to decide which files need to be updated: files with
       either  a  changed  size  or a changed checksum are selected for transfer.
       Since this whole-file checksumming of all files on both sides of the  con-
       nection  occurs  in  addition to the automatic checksum verifications that
       occur during a file's transfer, this option can be quite slow.

       Note that rsync always verifies that each transferred file  was  correctly
       reconstructed  on  the receiving side by checking its whole-file checksum,
       but that automatic after-the-transfer verification has nothing to do  with
       this  option's  before-the-transfer  "Does  this file need to be updated?"
       check.

Dies zeigt, wie Sie Probleme haben können, wenn Sie dieselben Größen- und Zeitstempel haben.

Die Einrichtung

$ cd /tmp

$ mkdir -p {A,b}/1/2/{3,4}

$ echo "\___________from A" | \
      tee A/1/2/x  | tee A/1/2/3/y  | tee A/1/2/4/z  | \
  tr A b | \
      tee b/1/2/x  | tee b/1/2/3/y  | tee b/1/2/4/z  | \
      tee b/1/2/x0 | tee b/1/2/3/y0 >     b/1/2/4/z0

$ find A b -type f | xargs -I% sh -c "echo %; cat %;"
A/1/2/3/y
\___________from A
A/1/2/4/z
\___________from A
A/1/2/x
\___________from A
b/1/2/3/y
\___________from b
b/1/2/3/y0
\___________from b
b/1/2/4/z
\___________from b
b/1/2/4/z0
\___________from b
b/1/2/x
\___________from b
b/1/2/x0
\___________from b

Der Rsync, der nichts kopiert, da alle Dateien die gleiche Größe und den gleichen Zeitstempel haben

$ rsync -avu A/ b
building file list ... done

sent 138 bytes  received 20 bytes  316.00 bytes/sec
total size is 57  speedup is 0.36

$ find A b -type f | xargs -I% sh -c "echo %; cat %;"
A/1/2/3/y
\___________from A
A/1/2/4/z
\___________from A
A/1/2/x
\___________from A
b/1/2/3/y
\___________from b
b/1/2/3/y0
\___________from b
b/1/2/4/z
\___________from b
b/1/2/4/z0
\___________from b
b/1/2/x
\___________from b
b/1/2/x0
\___________from b    

Der Rsync, der ordnungsgemäß funktioniert, da er Prüfsummen vergleicht

$ rsync -cavu A/ b
building file list ... done
1/2/x
1/2/3/y
1/2/4/z

sent 381 bytes  received 86 bytes  934.00 bytes/sec
total size is 57  speedup is 0.12

$ find A b -type f | xargs -I% sh -c "echo %; cat %;"
A/1/2/3/y
\___________from A
A/1/2/4/z
\___________from A
A/1/2/x
\___________from A
b/1/2/3/y
\___________from A
b/1/2/3/y0
\___________from b
b/1/2/4/z
\___________from A
b/1/2/4/z0
\___________from b
b/1/2/x
\___________from A
b/1/2/x0
\___________from b

funktioniert -c und -u gut zusammen?
Sergey Korzhov

@ SergeyKorzhov tut es. Das `-u 'funktioniert wie gewohnt nur dann, wenn das Ziel nicht neuer ist.
Bruno Bronosky

1

Dies ist das, was ich zum Sichern persönlicher Dateien verwende, bei denen mir nicht alles wichtig -aist und ich möchte , dass weitere nützliche Informationen gedruckt werden.

rsync -rtu --delete --info=del,name,stats2 "/home/<user>/<src>/" "/run/media/<user>/<drive>/<dst>"

Von der rsync-Manpage :

-r, --recursive Weist
rsync an, Verzeichnisse rekursiv zu kopieren.

-t, --times
Damit wird rsync angewiesen , die Änderungszeiten zusammen mit den Dateien zu übertragen und auf dem fernen System zu aktualisieren.

-u, --update
Dadurch wird rsync gezwungen , alle Dateien zu überspringen, die auf dem Ziel vorhanden sind und eine geänderte Zeit haben, die neuer als die Quelldatei ist. (Wenn eine vorhandene Zieldatei eine Änderungszeit aufweist, die der der Quelldatei entspricht, wird sie aktualisiert, wenn die Größen unterschiedlich sind.)

--delete
Hiermit wird rsync angewiesen , externe Dateien von der empfangenden Seite zu löschen (solche, die sich nicht auf der sendenden Seite befinden), jedoch nur für die Verzeichnisse, die synchronisiert werden.

--info = FLAGS Mit
dieser Option können Sie die Informationsausgabe, die Sie anzeigen möchten, genau steuern.

Von rsync --info=help

DEL        Mention deletions on the receiving side  
NAME       Mention 1) updated file/dir names, 2) unchanged names  
STATS      Mention statistics at end of run (levels 1-3)

Obwohl dies weniger explizit ist, scheint es äquivalent und kürzer zu sein:

rsync -rtuv --delete --info=stats2 "/home/<user>/<src>/" "/run/media/<user>/<drive>/<dst>"

-v, --verbose
Ein einzelnes -v gibt Auskunft darüber, welche Dateien übertragen werden, und am Ende eine kurze Zusammenfassung [stats1].


0

Dies ist nicht ganz das Gleiche, wonach Sie gefragt haben, aber Sie könnten die Verwendung eines Versionskontrolltools in Betracht ziehen. Tools wie Git machen alles, wonach Sie fragen, und mehr, besonders wenn Sie nicht direkt in Ordner B arbeiten, könnte es interessant sein, sie sich anzusehen. Weitere Informationen zu Git finden Sie hier


2
Dies funktioniert nur, wenn Sie alles zur Versionskontrolle hinzufügen möchten. Es erzwingt auch, dass jede jemals festgelegte Änderung dauerhaft gespeichert wird, was unerwünscht sein kann.
Qudit

@Qudit, das ist wahr, obwohl es über das Klonen möglich ist, den Verlauf zu begrenzen, aber die Begrenzung des Verlaufs ist (noch?) Nicht standardmäßig in Git implementiert.
switch87

@ switch87 Ja, ich weiß, dass Sie alte Commits löschen können. Die Versionskontrolle ist jedoch keine geeignete Lösung für generische Backups, insbesondere wenn große Binärdateien vorhanden sind.
Qudit

Seine Frage ist für die lokale Sicherung, aber wenn Sie es für die Remote-Sicherung verwenden, können Sie immer noch Git-Anhang für die größeren Dateien verwenden. Für lokale Backups ist dies kein Problem.
switch87

2
@ switch87 Das sollte eigentlich ein Kommentar zum Q und keine Antwort sein, da es nicht erklärt, wie Sie git verwenden würden, um Backups zu erstellen.
slm

0

Sie können es folgendermaßen verwenden:

rsync -avu --delete /home/user/A/* /home/user/B/

Auf diese Weise kopieren Sie den Inhalt von Ordner A in Ordner B und nicht den Inhalt von Ordner A selbst.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.