Jak wykonać mv folder w Linuksie zachowując swój mtime?

12

Korzystam z CentOS 5.5 i chciałbym przenieść dużą liczbę folderów w jednym woluminie , zachowując je mtime.

Najlepsze rozwiązanie, jakie mogłem znaleźć, to:

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

Przy ponad 1 TB danych w udziale NFS kopiowanie trwa wiecznie. Nie chcę kopiować. Chcę natychmiastowego ruchu.

Kiedy przenoszę folder za pomocą mv source/data target/, mtimefolder (nie pliki) zostaje ustawiony na bieżącą godzinę. Jest tak, ponieważ zawartość folderu, który przenoszę, zostaje zmodyfikowana przez tę operację ( ..pozycja wskazuje na inny i-węzeł).

Wymyśliłem następujący skrypt powłoki, który zadzwoniłem 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

Cóż, to też nie działało. Folder mtimezostał przywrócony, ale wszystkie foldery w folderze, które przenoszę (tylko te o głębokości 1 poziomu) otrzymują mtimereset z przyczyn, których nie rozumiem.

Czy ktoś ma właściwe, wydajne i prawidłowe rozwiązanie?

Roman Zenka
źródło
Zastanawiam się, dlaczego twoja próba touchnie zadziałała. Czy jest to mvkrok, czy touchkrok, który zmienia mtime podkatalogów? Jaki system operacyjny znajduje się na serwerze NFS i (jeśli wiesz) jaki typ systemu plików?
Gilles „SO- przestań być zły”
@Gilles: Nie wiem, dlaczego tak się dzieje. To mvkrok powoduje kłopoty. Serwer NFS jest w rzeczywistości pamięcią NetApp, nie wiem praktycznie nic o jego wewnętrznych elementach.
Roman Zenka,
1
Dzięki. Podejrzewam, że to dziwactwo NetApp. W przeciwnym razie touchpowinno było działać. Nawiasem mówiąc, byłby to bardziej przenośny sposób touch -r "$1" reference.tmp; mv -- "$1" "$2"; touch -r reference.tmp -- "$2"; rm reference.tmp.
Gilles „SO- przestań być zły”
@Gilles: Bardzo interesujące, nie zdawałem sobie sprawy, że nie statjest przenośny.
Roman Zenka,

Odpowiedzi:

15

POSIX mvnie zapewnia żadnej opcji żądania zachowania atime / mtime, ale ponieważ operacja jest lokalna dla tego samego woluminu, możesz poprosić cpo użycie twardych linków zamiast kopiowania danych zwykłych plików za pomocą -lopcji:

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

Ponieważ tylko katalogi i odwołania do plików zostaną faktycznie skopiowane, powinno pójść znacznie szybciej:

Więcej informacji na temat twardych linków można znaleźć na odpowiedniej stronie Wikipedii

Jeśli chodzi o to, dlaczego w bieżącym rozwiązaniu resetuje się podkatalogi mtime, to dlatego, że dostajesz i przywracasz tylko katalog macierzysty mtime: touch nie jest poleceniem rekurencyjnym.

Eureka
źródło
Czas mtime jest bardziej skomplikowany. Tylko katalog nadrzędny i katalogi bezpośrednio pod nim zmieniły mtime. Wszystkie pozostałe katalogi pozostają takie same. Można by oczekiwać, że zmieni się każdy katalog lub tylko rodzic.
Roman Zenka,
1
W rzeczywistości ma to sens: 1) Katalog nadrzędny ma dobry mtime, ponieważ został jawnie ustawiony za pomocą dotyku, 2) Wpisy katalogu zostały odtworzone w katalogu nadrzędnym, ale ich mtime nie został ręcznie przywrócony (struktura katalogu uniksowego i format i-węzła) 3) Reszta struktury drzewa nie została faktycznie zmieniona, ponieważ pozostaliśmy w tym samym wolumenie: dlatego mvnie ma opcji „rekurencyjnej”, zejście do podkatalogów odbywa się tylko wtedy, gdy potrzebna jest rzeczywista kopia (na przykład różne woluminy).
Eureka
@Eureka: Dobre wyjaśnienie, ale dlaczego tak się dzieje? Gdybym był do wdrożenia mvna katalogu data, chciałbym po prostu zmienić ..się w data„s zawartości i modyfikować sourcei targetkatalogów o wymienieniu Element został przeniesiony prawidłowo. Żadnych innych katalogów nie trzeba będzie dotykać.
Roman Zenka,
1
@Roman Zenka Po pewnym wyszukiwaniu to zachowanie wydaje się dość luźno określone między Uniksem a systemem plików i zależy od dużej części podstawowej renameimplementacji syscall przez jądro i używany system plików, a NFS dodaje swój udział w problemie. Istnieje pewien wskaźnik odnoszący się do tego rodzaju niespójności: patchwork.ozlabs.org/patch/25833 bugs.opensolaris.org/bugdatabase/…
Eureka
@Eureka: Bardzo trudno mi uwierzyć, że coś, co uważam za tak podstawowe, może być takim bałaganem. Jest prawie 2011 rok. Dzięki za te zasoby!
Roman Zenka,
4

Innym rozwiązaniem może być:

rsync -a --remove-source-files źródło / cel danych /

Genjo
źródło
To nie wydaje się działać w systemie macOS.
Lenar Hoyt,