Dateien verschieben und Verzeichnisse mit rsync löschen?

17

Vor kurzem musste ich eine große Anzahl von Dateien löschen (über 1 Million) und habe Folgendes gelesen:

rsync -av --delete `mktemp -d`/ ~/source && rmdir ~/source

War eine der optimiertesten Möglichkeiten, das zu tun, und ich kann dafür bürgen, dass es schneller ist als rm -rf.

Ich bin kein Experte auf diesem Gebiet, aber nach meinem Verständnis hat der Grund für die Leistung von rsync etwas mit der Art und Weise zu tun, wie Dateien aufgelistet werden (LIFO anstelle von FIFO, nehme ich an). Das Problem ist nun, dass ich auch eine große Anzahl von Dateien auf effiziente Weise verschieben muss. Nach einigem Suchen fand ich Folgendes:

rsync -av --ignore-existing --remove-source-files ~/source ~/destination

Während dies alle verschobenen Dateien in löscht ~/source, bleiben die Verzeichnisse dort. Da ich eine "Round-Robin" -ähnliche Verzeichnisstruktur habe, liegt die Anzahl von files/directoriessehr nahe bei 1, so dass ich gezwungen bin, den ersten Befehl erneut auszuführen, um das Verzeichnis vollständig zu entfernen:

rsync -av --ignore-existing --remove-source-files ~/source ~/destination && \
rsync -av --delete `mktemp -d`/ ~/source && rmdir ~/source

Ein Straight mvwürde praktisch sofort beendet, aber mein ~/destinationVerzeichnis enthält Dateien, die aufbewahrt werden sollten, daher mvist dies keine Option. Ich habe die Optionen --prune-empty-dirsund --forcersync gefunden, aber keine scheint wie erwartet zu funktionieren:

--force                 force deletion of directories even if not empty
--prune-empty-dirs      prune empty directory chains from the file-list
--remove-source-files   sender removes synchronized files (non-dirs)

Gibt es eine Möglichkeit, einen Schritt mit rsync auf einmal nachzuahmen ?

Alix Axel
quelle
2
Wenn Sie hier keine Antwort erhalten, veröffentlichen Sie sie in der rsync-Liste. Sie sind sehr hilfreich. lists.samba.org/mailman/listinfo/rsync
Joe
related: superuser.com/questions/676671/…
Ciro Santilli

Antworten:

7

Ich fand diesen Thread im Stackoverflow mit dem Titel: Löschen von Ordnern mit rsync "move"? , die im Wesentlichen die gleiche Frage stellt. Eine der Antworten schlug vor, die rsyncin 2-Befehle auszuführen, da anscheinend kein einziger Befehl vorhanden ist, der das Verschieben / Entfernen der Dateien und der Quellverzeichnisse ausführen kann.

$ rsync -av --ignore-existing --remove-source-files source/ destination/ && \
  rsync -av --delete `mktemp -d`/ source/ && rmdir source/

Alternativ können Sie diesen Befehl verwenden:

$ rsync -axvvES --remove-source-files source_directory /destination/ && \
  rm -rf source_directory

Nicht ideal, aber macht den Job.

slm
quelle
Ja, ich habe diese Frage beantwortet (und die gleiche "Lösung" gibt es auch für diese Frage). = P
Alix Axel
@AlixAxel - Ha, tut mir leid, dass ich nicht einmal bemerkt habe, dass du auf diese Frage geantwortet hast. Naja. Soll ich diese Antwort dann löschen?
SLM
3
Mit rsyncPrune Verzeichnisse fühlt sich nicht richtig und es gibt immer die Gefahr mit rm -rf. Ich würde den 2. Schritt empfehlen:find source/ -d -type d -exec rmdir {} \;
Zany
2
Ich fühle mich einfach gezwungen zu geben, nie verwenden -deleteund --remove-source-filesin einem einzigen Befehl rsync (die obigen Beispiele sind in Ordnung, das ist tangential). Wenn Sie unterbrechen und dann erneut ausführen, was ich beschreibe, gehen die übertragenen Dateien verloren. Was ich schon gemacht habe :(
Sridhar Sarnobat
Beim Aufräumen findbevorzuge find source/ -type d -empty -delete ich Folgendes : Es gibt mir ein seltsames Gefühl der Gewissheit, dass es nicht einfach alles kaputt macht.
Greyfade
10

Vom Kommentar von zany zur Antwort von slm ( Dateien verschieben und Verzeichnisse mit rsync löschen? ) Ich würde diese 2 Befehle als Antwort empfehlen:

rsync -av --ignore-existing --remove-source-files source/ destination/ && \
find source/ -depth -type d  -empty -exec rmdir "{}" \;

Der Vorteil ist, wie zany schon sagte, dass die Verwendung von rm -rf immer noch eine gewisse Gefahr birgt, wenn Sie es nicht richtig machen oder für Anfänger.

Ich habe 2 Optionen hinzugefügt, -depth und -empty, und obwohl ich nicht sicher bin, ob dies wirklich notwendig ist, macht es den 2. Befehl für andere Situationen portabler und sogar sicherer (es macht immer noch das Richtige, wenn einige Verzeichnisse nicht leer sind und beginnt vom tiefsten Punkt in einem Verzeichnisbaum zu entfernen)

mit
quelle
warum nicht einfach -deletestatt -exec rmdir {} \;?
fliegende Schafe
@flying_sheep Siehe user7000's Kommentar in der Antwort von sim: Wenn rsync unterbrochen wird, können Dateien verloren gehen
mit
Wenn rsync unterbrochen wird, wird der Suchvorgang nie gestartet oder nicht? Das -Löschen in einem zweiten rsync sollte also kein Problem sein. -Delete entfernt aber auch Dateien, stattdessen löscht rmdir niemals Dateien, sondern nur Verzeichnisse. Beide (-delete und rmdir) überprüfen die Verzeichnisse vor dem Löschen, ob sie leer sind.
Benba
Außerdem steht auf den Manpages, dass du -execdir anstelle von -exec ... verwenden sollst
benba
2

Dies erledigt die Arbeit in einem Schritt. Beachten Sie den abschließenden / Schrägstrich / sowohl auf dem Quell- als auch auf dem Zielpfad.

rsync \
    -ruval \
    --ignore-existing \
    --remove-source-files \
    --prune-empty-dirs \ 
    /source/path/ /target/path/

Ich wiederhole die Warnung von user7000, nicht zu benutzen --deleteund --remove-source-filesgemeinsam im selben Anruf zu tätigen rsync. Wenn der Vorgang fehlschlägt oder unterbrochen wird und derselbe Anruf wiederholt wird, gehen Daten verloren. Wenn in jedem Zweifel, verwenden Sie die --dry-runOption , um zu sehen , was getan werden würde.

gjvc
quelle
-ruvalscheint überflüssig. -aist gleichbedeutend mit -rlptgoD, was sowohl -rals auch enthält -l.
greyfade