Wie kann ich einen Ordner in Linux bearbeiten, der seine mtime beibehält?

12

Ich verwende CentOS 5.5 und möchte eine große Anzahl von Ordnern innerhalb eines Volumes verschieben , wobei deren Größe erhalten bleibt mtime.

Die beste Lösung, die ich finden konnte, ist wie folgt:

cp -p -r source/data target/
rm -rf source/data

Mit mehr als 1 TB Daten auf einer NFS-Freigabe dauert das Kopieren ewig. Ich möchte nicht kopieren. Ich möchte sofort umziehen.

Wenn ich einen Ordner mit verschiebe mv source/data target/, wird die mtimeUhrzeit des Ordners (nicht der Dateien) auf die aktuelle Uhrzeit eingestellt. Dies liegt daran, dass der Inhalt des Ordners, den ich verschiebe, durch diesen Vorgang geändert wird (der ..Eintrag verweist auf einen anderen Inode).

Ich habe mir ein Shell-Skript ausgedacht, das ich aufgerufen habe mv_preserve_mtime.sh:

#!/bin/bash
# Moves source folder to target folder. 
# You are responsible for making sure the target does not exist, otherwise this blows up
export timestamp=`stat -c %y $1`
mv "$1" "$2"
touch --date="${timestamp}" $2

Nun, das hat auch nicht funktioniert. Der Ordner mtimewird wiederhergestellt, aber alle Ordner in dem Ordner, den ich verschiebe (nur die Ordner mit einer Tiefe von 1 Ebene) werden mtimeaus Gründen, die ich nicht verstehe, zurückgesetzt.

Hat jemand eine richtige, effiziente und korrekte Lösung?

Roman Zenka
quelle
Ich frage mich, warum dein Versuch mit touchnicht geklappt hat. Ist es der mvSchritt oder der touchSchritt, der die Zeit der Unterverzeichnisse ändert? Welches Betriebssystem befindet sich auf dem NFS-Server und (falls bekannt) welcher Dateisystemtyp?
Gilles
@ Gilles: Ich weiß nicht warum es passiert. Es ist der mvSchritt, der Ärger verursacht. Der NFS-Server ist eigentlich ein NetApp-Speicher, ich weiß so gut wie nichts über seine Interna.
Roman Zenka
1
Vielen Dank. Ich vermute, es ist eine Seltsamkeit von NetApp. Ansonsten touchhätte das funktionieren sollen. Übrigens wäre ein tragbarer Weg touch -r "$1" reference.tmp; mv -- "$1" "$2"; touch -r reference.tmp -- "$2"; rm reference.tmp.
Gilles
@Gilles: Sehr interessant, wusste nicht, statwar nicht tragbar.
Roman Zenka

Antworten:

15

POSIX mvbietet keine Option, um die Beibehaltung von Uhrzeit und Uhrzeit anzufordern. Da der Vorgang jedoch lokal für dasselbe Volume ausgeführt wird, können Sie die cpVerwendung von Hardlinks anfordern, anstatt die Daten der regulären Dateien mithilfe der folgenden -lOption zu kopieren :

cp -p -r -l source/date target/
rm -rf source/data

Da nur Verzeichnisse und Dateiverweise kopiert werden, sollte es viel schneller gehen:

Weitere Informationen zu Hardlinks finden Sie auf der entsprechenden Wikipedia-Seite

Die Ursache für das Zurücksetzen der Unterverzeichnisse mtime mit Ihrer aktuellen Lösung liegt darin, dass Sie nur das übergeordnete Verzeichnis mtime abrufen und wiederherstellen: touch ist kein rekursiver Befehl.

Eureka
quelle
Die Zeit ist komplizierter. Nur das übergeordnete Verzeichnis und die Verzeichnisse direkt darunter haben sich zeitlich geändert. Alle anderen Verzeichnisse bleiben gleich. Man würde erwarten, dass entweder jedes einzelne Verzeichnis geändert wird oder nur das übergeordnete.
Roman Zenka
1
Eigentlich macht es Sinn: 1) Das übergeordnete Verzeichnis hat die gute mtime, weil es explizit per Touch festgelegt wurde, 2) Die Verzeichniseinträge wurden mit dem übergeordneten Verzeichnis neu erstellt, aber ihre mtime wurde nicht manuell wiederhergestellt (Unix-Verzeichnisstruktur und Inode-Format). 3) Der Rest der Baumstruktur wurde nicht wirklich geändert, da wir auf demselben Volume blieben: Aus diesem Grund mvgibt es keine "rekursive" Option, ein Abstieg in Unterverzeichnisse wird nur durchgeführt, wenn eine tatsächliche Kopie (zum Beispiel verschiedene Volumes) benötigt wird.
Eureka
@Eureka: Gute Erklärung, aber warum wird das so gemacht? Wenn ich zu implementieren war mvin einem Verzeichnis data, würde ich einfach die Änderung ..in den data‚s Inhalt und ändern Sie die sourceund targetVerzeichnisse richtig die verschobene Artikel aufzulisten. Keine anderen Verzeichnisse müssten berührt werden.
Roman Zenka
1
@Roman Zenka Nach einigen Suchvorgängen scheint dieses Verhalten zwischen Unices und Dateisystemen ziemlich locker zu sein und von einem Großteil der zugrunde liegenden renameSyscall-Implementierung durch den Kernel und die verwendeten Dateisysteme abhängig zu sein , wobei NFS seine Freigabe zum Problem hinzufügt. Es gibt einige Verweise auf diese Art von Inkonsistenzen: patchwork.ozlabs.org/patch/25833 bugs.opensolaris.org/bugdatabase/…
Eureka
@Eureka: Ich finde es extrem schwer zu glauben, dass etwas, das ich für so grundlegend halte, so ein Durcheinander sein kann. Es ist fast 2011. Vielen Dank für diese Ressourcen!
Roman Zenka
4

Eine andere Lösung kann sein:

rsync -a - entferne-Quelldateien Quelle / Datenziel /

Genjo
quelle
Dies scheint unter macOS nicht zu funktionieren.
Lenar Hoyt