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:
rsync
kann den Inhalt eines Verzeichnisses in ein anderes zusammenführen (idealerweise mit--remove-source-files
Option zum sicheren Löschen nur der Quelldateien, die erfolgreich übertragen wurden, und mit der üblichen Berechtigungs-/Eigentums-/Zeiterhaltungsoption-a
wenn Sie möchten)
… aber dies ist ein vollständiger Kopiervorgang und kann daher sehr plattenintensiv sein.- Aktuell bevorzugte Option: Sie können
rsync
kombinieren ist--link-dest=DIR
Option (um Hardlinks zu erstellen, anstatt Dateiinhalte zu kopieren, wo möglich) und--remove-source-files
um eine Semantik zu erhalten, die einem normalenmv
sehr ähnlich ist .
Dazu--link-dest
muss ein absoluter Pfad zur Quelle angegeben werden Verzeichnis (oder ein relativer Pfad vom Ziel zur Quelle ).
… aber dies verwendet--link-dest
auf 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
find
verwenden 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) cp
kann harte Links erstellen (einfach ausgedrückt zusätzliche Verweise auf dieselbe vorhandene Datei), was ein Ergebnis erzeugt, das dem Zusammenführen vonmv
sehr ä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.