Comment mv un dossier sous Linux en conservant son mtime?


12

J'utilise CentOS 5.5 et je souhaite déplacer une grande quantité de dossiers dans un volume , en conservant leur mtime.

La meilleure solution que j'ai pu trouver est la suivante:

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

Avec plus de 1 To de données sur un partage NFS, la copie prend une éternité. Je ne veux pas copier. Je veux un mouvement instantané.

Lorsque je déplace un dossier à l'aide de mv source/data target/, le mtimedossier (et non les fichiers) est réglé sur l'heure actuelle. En effet, le contenu du dossier que je déplace est modifié par cette opération (l' ..entrée pointe vers un autre inode).

J'ai trouvé un script shell suivant que j'ai appelé 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

Eh bien, cela n'a pas fonctionné non plus. Le dossier mtimeest restauré, mais tous les dossiers du dossier que je déplace (seulement ceux de 1 niveau de profondeur) sont mtimeréinitialisés pour des raisons que je ne comprends pas.

Quelqu'un a-t-il une solution appropriée, efficace et correcte?


Je me demande pourquoi votre tentative touchn'a pas fonctionné. Est-ce l' mvétape ou l' touchétape qui modifie le mtime des sous-répertoires? Quel système d'exploitation est sur le serveur NFS et (si vous le savez) quel type de système de fichiers?
Gilles 'SO- arrête d'être méchant'

@ Gilles: Je ne sais pas pourquoi cela se produit. C'est l' mvétape qui cause des ennuis. Le serveur NFS est en fait un stockage NetApp, je ne sais pratiquement rien de ses composants internes.
Roman Zenka

1
Merci. Je soupçonne que c'est une bizarrerie NetApp. Sinon, touchaurait dû fonctionner. Soit dit en passant, un moyen plus portable serait touch -r "$1" reference.tmp; mv -- "$1" "$2"; touch -r reference.tmp -- "$2"; rm reference.tmp.
Gilles 'SO- arrête d'être méchant'

@ Gilles: Très intéressant, je ne savais pas que ce statn'était pas portable.
Roman Zenka

Réponses:


15

POSIX mvne fournit aucune option pour demander la conservation atime / mtime, mais comme l'opération est locale sur un même volume, vous pouvez demander cpà utiliser des liens physiques au lieu de copier les données des fichiers normaux en utilisant l' -loption:

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

Étant donné que seuls les répertoires et les références de fichiers seront réellement copiés, cela devrait aller beaucoup plus vite:

Pour plus d'informations sur les liens physiques, vous pouvez consulter la page Wikipedia correspondante

Quant à savoir pourquoi les sous-répertoires mtime sont réinitialisés avec votre solution actuelle, c'est parce que vous obtenez et restaurez uniquement le répertoire parent mtime: touch n'est pas une commande récursive.


Le mtime est plus compliqué que ça. Seul le répertoire parent et les répertoires directement en dessous ont changé mtime. Tous les autres répertoires restent les mêmes. On peut s'attendre à ce que chaque répertoire soit modifié, ou seulement le parent.
Roman Zenka

1
En fait, cela a du sens: 1) Le répertoire parent a le bon mtime car il a été explicitement défini par le toucher, 2) Les entrées du répertoire ont été recréées avec le répertoire parent, mais leur mtime n'a pas été restauré manuellement (structure de répertoire Unix et format inode) 3) Le reste de la structure arborescente n'a pas été réellement modifié, car nous sommes restés sur le même volume: c'est pourquoi mvn'a pas d'option "récursive", la descente dans les sous-répertoires n'est effectuée que si une copie réelle (différents volumes, par exemple) est nécessaire.
Eureka

@Eureka: Bonne explication, mais pourquoi est-ce fait de cette façon? Si je devais implémenter mvsur un répertoire data, je changerais simplement le ..dans le datacontenu de et modifierais les répertoires sourceet targetpour lister correctement l'élément déplacé. Aucun autre répertoire n'aurait besoin d'être touché.
Roman Zenka

1
@Roman Zenka Après quelques recherches, ce comportement semble être plutôt vaguement spécifié entre les Unices et les systèmes de fichiers et dépendre d'une grande partie de l' renameimplémentation syscall sous-jacente par le noyau et le ou les systèmes de fichiers utilisés, NFS ajoutant son partage au problème. Il existe des pointeurs référençant ce type d'incohérences: patchwork.ozlabs.org/patch/25833 bugs.opensolaris.org/bugdatabase/…
Eureka

@Eureka: Je trouve extrêmement difficile de croire que quelque chose que je considérerais si basique puisse être un tel gâchis. Nous sommes presque 2011. Merci pour ces ressources!
Roman Zenka

4

Une autre solution peut être:

rsync -a --remove-source-files source / cible de données /


Cela ne semble pas fonctionner sur macOS.
Lenar Hoyt
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.