RSYNC löscht keine Quellverzeichnisse

27

Ich verwende Rsync, um wichtige Dateien von einem Server abzurufen, und lösche die Dateien dann vom Server, sobald ich sie lokal habe. Der vollständige Befehl, den ich ausführe, ist unten.

Dadurch werden die Dateien auf dem Quellserver erfolgreich gelöscht , es verbleiben jedoch noch leere Verzeichnisse. Ich erhalte keine Nachrichten oder Fehler. Alle Ausgaben sind normal. Vielleicht ist dies die beabsichtigte Funktionalität.

Wie kann ich rsync anweisen, alles einschließlich der Verzeichnisse zu bereinigen?

rsync --progress -vrzh --remove-source-files

Version ist 3.0.9 an beiden Enden.

Sajan Parikh
quelle

Antworten:

13

Das Verhalten --remove-source-files, das Sie beobachten, ist genau das, das angegeben wird durch man rsync:

--remove-source-files

   This tells rsync to remove from the sending side the files (meaning non-directories) that are a part of the transfer and have been successfully duplicated on the receiving side.

Es gibt keinen speziellen Befehl zum Entfernen der Verzeichnisse, wie diese beiden Diskussionen in StackExchange und ServerFault deutlich zeigen. Die dort vorgeschlagene Lösung besteht darin, zwei separate Befehle auszugeben:

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

Das letzte Stück des Befehls in diesen beiden Beiträgen vorgeschlagen,

 rmdir source/

Das zum Entfernen des (jetzt geleerten) Quellverzeichnisses erforderliche Formular befindet sich in diesen Posts, da die OPs und die Antworten rsync verwenden, um große Mengen von Dateien auf demselben Computer zu verschieben. In Ihrem Fall müssen Sie dies manuell tun.

MariusMatutiae
quelle
5
Der rsync --deleteVorschlag ist gefährlich, da er die Möglichkeit ignoriert, dass der rsync-Vorgang nicht abgeschlossen wurde oder neue Dateien an der Quelle vorhanden sind. Die folgende findMethode von @ slhck ist viel sicherer.
Sai
29

Die Manpage sagt sogar:

--remove-source-files   sender removes synchronized files (non-dirs)

Wenn Sie leere Verzeichnisse in Ihrer Quelle entfernen möchten, gehen Sie wie folgt vor, wenn noch Dateien vorhanden sind:

find . -depth -type d -empty -delete

Aber für ein leeres Root-Verzeichnis reicht rm -rf <directory>natürlich ein Wille aus.

slhck
quelle
5
Ja, das ist die einzige Lösung. Es ist eine dumme fehlende Funktion von Rsync. Rsync weiß, wann die letzte Datei in einem Verzeichnis verarbeitet wurde. Es ist einfach genug, das Verzeichnis auch zu entfernen, wenn es leer ist.
Erik Aronesty
4
Beachten Sie, dass die Ausgabe von "rm -rf" rennbedingte Probleme mit sich bringt, und ich rate davon ab.
Raúl Salinas-Monteagudo
Variante, die das leere Verzeichnis der obersten Ebene nicht löscht:find some_dir -depth -type d -empty -not -path some_dir -delete
Cameron Tacklind
5

Die Verwendung von " rm -rf " hat eine inhärente Racebedingung. Sie können nämlich Dateien löschen, die gerade zwischen rsync und rm erstellt wurden Aufruf erstellt wurden.

Ich bevorzuge zu verwenden:

rsync --remove-source-files -a server: Posteingang / Posteingang / &&

SSH-Server finden eingehende-Typ d -delete

Dadurch werden die Verzeichnisse NICHT entfernt, wenn sie nicht leer sind.

Raúl Salinas-Monteagudo
quelle
2
Dadurch rm -rfwerden auch Dateien entfernt, die aus irgendeinem Grund nicht übertragen wurden.
Kristian
1
In dieser Antwort fehlt die -depthOption, die anweist find, in der richtigen Reihenfolge zu verarbeiten. Infolge dieses Fehlers werden Verzeichnisse, die (möglicherweise rekursiv) nur leere Verzeichnisse enthalten, nicht gelöscht. Die Variante von @slhck hat es richtig.
Stéphane Gourichon
1

-m, --prune-empty-dirs Entfernen Sie leere Verzeichnisketten aus der Dateiliste

--force Löschung von Verzeichnissen erzwingen, auch wenn diese nicht leer sind

MarcoP
quelle
1
Dadurch wird nur verhindert, dass rsync leere Verzeichnisse kopiert. Es werden keine leeren Verzeichnisse gelöscht.
Navin
1

Entfernen Sie die Quelldateien und anschließend aus Sicherheitsgründen die Verzeichnisse.

# given this scenario where you generate folders 2014-01-01 etc.. that have an archive myfile.tar.gz
pushd $(mktemp -d)
mkdir 201{4..6}-{01..12}-{01..31}
for i in $(ls); do; touch $i/myfile.tar.gz;done;
# find and rsync on 10 CPU threads directories that match ./2015-*
find /tmp/tmp.yjDyF1jN70/src -type d -name '2015-*' | \
parallel \
--jobs 10 \
--progress \
--eta \
--round-robin \
rsync \
--hard-links \
--archive --verbose --protect-args \
--remove-source-files \
{} /tmp/tmp.yjDyF1jN70/dest
# now safely remove empty directories only
for i in $(ls /tmp/tmp.yjDyF1jN70/src); do; rmdir /tmp/tmp.yjDyF1jN70/src/$i; done;

Mehr zu GNU Parallel

Daniel Andrei Mincă
quelle