Wenn ich mv verwende Um einen Ordner namens „Ordner“ in ein Verzeichnis zu verschieben, das bereits „Ordner“ enthält, werden sie zusammengeführt oder wird er ersetzt?
Akzeptierte Antwort:
mv Verzeichnisse nicht zusammenführen oder überschreiben können, schlägt dies mit der Meldung “mv:cannot move ‘a’ to ‘b’:Directory not empty” fehl , auch wenn Sie --force verwenden Option.
Sie können dies mit anderen Tools (wie rsync) umgehen , find , oder sogar cp ), aber Sie müssen die Auswirkungen sorgfältig abwägen:
rsynckann den Inhalt eines Verzeichnisses in ein anderes zusammenführen (idealerweise mit--remove-source-filesOption zum sicheren Löschen nur der Quelldateien, die erfolgreich übertragen wurden, und mit der üblichen Berechtigungs-/Eigentums-/Zeiterhaltungsoption-awenn Sie möchten)
… aber dies ist ein vollständiger Kopiervorgang und kann daher sehr plattenintensiv sein.- Aktuell bevorzugte Option: Sie können
rsynckombinieren ist--link-dest=DIROption (um Hardlinks zu erstellen, anstatt Dateiinhalte zu kopieren, wo möglich) und--remove-source-filesum eine Semantik zu erhalten, die einem normalenmvsehr ähnlich ist .
Dazu--link-destmuss ein absoluter Pfad zur Quelle angegeben werden Verzeichnis (oder ein relativer Pfad vom Ziel zur Quelle ).
… aber dies verwendet--link-destauf unbeabsichtigte Weise (was zu Komplikationen führen kann oder auch nicht), erfordert die Kenntnis (oder Bestimmung) des absoluten Pfads zur Quelle (als Argument für--link-dest). ) und hinterlässt wieder eine leere Verzeichnisstruktur, die gemäß .
bereinigt werden muss - Sie können
findverwenden um die Quellverzeichnisstruktur am Ziel sequenziell neu zu erstellen und dann die eigentlichen Dateien einzeln zu verschieben
… aber dies muss mehrmals durch die Quelle laufen und kann auf Race-Bedingungen stoßen (neue Verzeichnisse werden während des mehrstufigen Prozesses an der Quelle erstellt) cpkann harte Links erstellen (einfach ausgedrückt zusätzliche Verweise auf dieselbe vorhandene Datei), was ein Ergebnis erzeugt, das dem Zusammenführen vonmvsehr ähnlich ist (und ist sehr IO-effizient, da nur Pointer erzeugt und keine eigentlichen Daten kopiert werden müssen)
… aber dies leidet wiederum unter einer möglichen Racebedingung (neue Dateien an der Quelle werden gelöscht, obwohl sie im vorherigen Schritt nicht kopiert wurden)
Welche dieser Problemumgehungen (falls vorhanden) angemessen ist, hängt stark von Ihrem spezifischen Anwendungsfall ab.
Denken Sie wie immer nach, bevor Sie einen dieser Befehle ausführen, und legen Sie Sicherungskopien an.
1:Beachten Sie, dass rsync --remove-source-files löscht keine Verzeichnisse, also müssen Sie so etwas wie find -depth -type d -empty -delete tun danach, um den leeren Quellverzeichnisbaum loszuwerden.