Как сохранить папку в Linux, сохранив ее mtime?

12

Я использую CentOS 5.5 и хотел бы перемещать большое количество папок в пределах одного тома , сохраняя их mtime.

Лучшее решение, которое я смог найти, это:

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

С более чем 1 ТБ данных на общем ресурсе NFS копирование занимает вечность. Я не хочу копировать. Я хочу мгновенного движения.

Когда я перемещаю папку с помощью mv source/data target/, mtimeдля папки (не для файлов) устанавливается текущее время. Это потому, что содержимое папки, которую я перемещаю, модифицируется этой операцией ( ..запись указывает на другой индекс).

Я придумал следующий сценарий оболочки, который я назвал 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

Ну, это тоже не сработало. Папка mtimeвосстанавливается, но все папки в папке, которую я перемещаю (только 1 уровень глубиной), mtimeсбрасываются по причинам, которые я не понимаю.

У кого-нибудь есть правильное, эффективное и правильное решение?

Роман Зенка
источник
Интересно, почему твоя попытка touchне сработала? Это mvшаг или touchшаг, который меняет mtime подкаталогов? Какая ОС находится на сервере NFS и (если вы знаете), какой тип файловой системы?
Жиль "ТАК - перестань быть злым"
@ Жиль: я не знаю, почему это происходит. Это mvшаг, который вызывает проблемы. Сервер NFS на самом деле является хранилищем NetApp, я практически ничего не знаю о его внутренностях.
Роман Зенка
1
Спасибо. Я подозреваю, что это странность NetApp. В противном случае touchдолжно было работать. Кстати более портативный способ был бы touch -r "$1" reference.tmp; mv -- "$1" "$2"; touch -r reference.tmp -- "$2"; rm reference.tmp.
Жиль "ТАК - перестань быть злым"
@ Жиль: Очень интересно, не понял, statне был портативным.
Роман Зенка

Ответы:

15

POSIX mvне предоставляет никакой возможности запрашивать сохранение atime / mtime, но, поскольку операция является локальной для того же тома, вы можете попросить cpиспользовать жесткие ссылки вместо копирования данных из обычных файлов, используя -lопцию:

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

Так как на самом деле будут скопированы только каталоги и ссылки на файлы, это должно идти намного быстрее:

Для получения дополнительной информации о жестких ссылках, вы можете обратиться к соответствующей странице Википедии

Что касается того, почему подкаталоги mtime сбрасываются с вашим текущим решением, это потому, что вы получаете и восстанавливаете только родительский каталог mtime: touch не является рекурсивной командой.

эврика
источник
Mtime сложнее, чем это. Только родительский каталог и каталоги непосредственно под ним изменились mtime. Все остальные каталоги остаются прежними. Можно ожидать, что будет изменен либо каждый отдельный каталог, либо только родительский.
Роман Зенка
1
На самом деле, это имеет смысл: 1) у родительского каталога хорошее mtime, потому что оно было явно установлено касанием, 2) записи каталога были воссозданы с родительским каталогом, но их mtime не было восстановлено вручную (структура каталогов Unix и формат inode) 3) Остальная часть древовидной структуры фактически не изменилась, так как мы остались на том же томе: поэтому mvу нас нет «рекурсивной» опции, переход по подкаталогам выполняется только в том случае, если необходимо фактическое копирование (например, разных томов).
Эврика
@Eureka: Хорошее объяснение, но почему это так? Если бы я реализовал mvкаталог data, я бы просто изменил содержимое ..in и изменил каталоги and, чтобы правильно отобразить перемещенный элемент. Никаких других каталогов не нужно было бы трогать. datasourcetarget
Роман Зенка
1
@Roman Zenka После некоторого поиска это поведение, по-видимому, довольно слабо определено между Unices и файловыми системами и зависит от базовой renameреализации syscall ядром и используемой файловой системой (-ами), NFS добавляет свою долю в проблему. Есть некоторые указатели, ссылающиеся на этот тип несоответствий: patchwork.ozlabs.org/patch/25833 bugs.opensolaris.org/bugdatabase/…
Eureka
@Eureka: мне очень трудно поверить, что что-то, что я бы посчитал настолько простым, может быть таким беспорядком. Это почти 2011 год. Спасибо за эти ресурсы!
Роман Зенка
4

Другое решение может быть:

rsync -a --remove-source-files источник / цель данных /

Genjo
источник
Это, похоже, не работает на MacOS.
Ленар Хойт