web-dev-qa-db-fra.com

Je viens de "mv" éditer un répertoire de 49 Go vers un mauvais chemin de fichier, est-il possible de restaurer l'état d'origine des fichiers?

J'ai (enfin, j'ai eu ) un répertoire:

/media/admin/my_data

Il mesurait environ 49 Go et contenait des dizaines de milliers de fichiers. Le répertoire est le point de montage d'une partition LUKS active.

Je voulais renommer le répertoire en:

/media/admin/my_data_on_60GB_partition

Je ne m'en rendais pas compte à l'époque, mais j'ai émis la commande depuis le répertoire personnel, j'ai donc fini par faire:

~% Sudo mv /media/admin/my_data my_data_on_60GB_partition

Alors, le programme mv a commencé à déplacer /media/admin/my_data et son contenu dans un nouveau répertoire ~/my_data_on_60GB_partition.

J'ai utilisé Ctrl + C pour annuler la commande à mi-chemin, j'ai maintenant tout un tas de fichiers répartis dans plusieurs répertoires:

~/my_data_on_60GB_partition    <---  about 2GB worth files in here

et

/media/admin/my_data           <---- about 47GB of orig files in here    

Le nouveau répertoire ~/my_data_on_60GB_partition et certains de ses sous-répertoires appartiennent à root.
Je suppose que le programme mv doit avoir copié les fichiers en tant que root au départ, puis après le transfert chown 'les a réédités sur mon compte utilisateur.

J'ai une sauvegarde un peu ancienne du répertoire/partition.
Ma question est, est-il possible de restaurer de manière fiable le tas de fichiers qui ont été déplacés?

Autrement dit, puis-je simplement exécuter:

Sudo mv ~/my_data_on_60GB_partition/*  /media/admin/my_data

ou dois-je renoncer à essayer de récupérer, car les fichiers sont peut-être corrompus et partiellement complets, etc.?

  • OS - Ubuntu 16.04
mv --version  
mv (GNU coreutils) 8.25
59
the_velour_fog

Lors du déplacement de fichiers entre des systèmes de fichiers, mv ne supprime pas un fichier avant d'avoir fini de le copier, et il traite les fichiers de manière séquentielle (j'ai d'abord dit qu'il copie puis supprime chaque fichier à son tour, mais ce n'est pas garanti - au moins = GNU mv copie puis supprime chaque argument de ligne de commande à son tour, et POSIX spécifie ce comportement ). Vous devriez donc avoir au plus un fichier incomplet dans le répertoire cible, et l'original sera toujours dans le répertoire source.

Pour reculer, ajoutez le -i flag donc mv n'écrase rien:

Sudo mv -i ~/my_data_on_60GB_partition/* /media/admin/my_data/

(en supposant que vous n'avez pas de fichiers cachés à restaurer à partir de ~/my_data_on_60GB_partition/), ou mieux encore (étant donné que, comme vous l'avez découvert, vous pouvez avoir de nombreux fichiers en attente de suppression), ajoutez le -n flag so mv n'écrase rien mais ne vous pose pas de question à ce sujet:

Sudo mv -n ~/my_data_on_60GB_partition/* /media/admin/my_data/

Vous pouvez également ajouter le -v flag pour voir ce qui se fait.

Avec tout mv compatible POSIX, la structure du répertoire d'origine doit toujours être intacte, vous pouvez donc vérifier cela - et simplement supprimer /media/admin/my_data... (Dans le cas général, je pense que le mv -n la variante est l'approche sûre - elle gère toutes les formes de mv, y compris par exemple mv /media/admin/my_data/* my_data_on_60GB_partition/.)

Vous devrez probablement restaurer certaines autorisations; vous pouvez le faire en masse en utilisant chown et chmod, ou les restaurer à partir de sauvegardes en utilisant getfacl et setfacl (merci à Sato Katsura pour le rappel ).

88
Stephen Kitt

Après avoir obtenu la réponse de Stephen Kitt et discuté de cette commande comme solution potentielle:

Sudo mv -i ~/my_data_on_60GB_partition/* /media/admin/my_data/

J'ai décidé de ne pas l'exécuter jusqu'à ce que je comprenne ce qui se passait, cette réponse décrit ce que j'ai découvert et fini par faire.

J'utilise Gnu mv qui copie les fichiers vers la cible, puis seulement si l'opération de copie réussit, il supprime l'original.
Cependant, je voulais confirmer si mv exécute cette séquence un fichier à la fois, si c'était vrai, le contenu du dossier d'origine aurait été proprement découpé en deux parties, une partie déplacée vers le destination, l'autre restant à la source. Et peut-être qu'il y aurait un fichier qui a été interrompu pendant la copie qui serait commun aux deux répertoires - et il serait probablement mal formé.

Pour découvrir les fichiers communs aux deux répertoires, j'ai exécuté:

~% Sudo diff -r --report-identical-files my_data_on_60GB_partition/. /media/admin/mydata/. | grep identical | wc -l
14237

Ce résultat suggère qu'il y avait 14 237 instances des mêmes fichiers dans les répertoires source et cible, j'ai confirmé en vérifiant les fichiers manuellement - oui, il y avait beaucoup des mêmes fichiers dans les deux répertoires. Cela suggère que ce n'est qu'après que mv copie une grande partie des fichiers qu'il effectue la suppression des fichiers source. Une recherche rapide dans la commande info sur mv a montré

Il [mv] utilise d'abord une partie du même code utilisé par cp -a pour copier les répertoires et fichiers demandés, puis (en supposant que la copie a réussi), il supprime les originaux. Si la copie échoue, la partie copiée sur la partition de destination est supprimée.

Je n'ai pas exécuté la commande mais je soupçonne que si j'ai essayé de l'exécuter

Sudo mv -i ~/my_data_on_60GB_partition/* /media/admin/my_data/

Le -iDemander avant d'écraser aurait probablement déclenché plus de 14 000 fois.

Alors, pour savoir combien de fichiers au total dans le répertoire nouvellement créé:

~% Sudo find my_data_on_60GB_partition/ -type f -a -print | wc -l                                                                    
14238

Donc, s'il y avait un total de 14238 fichiers réguliers dans le nouveau répertoire et 14237 avaient des originaux identiques dans la source, cela signifie qu'il n'y avait qu'un seul fichier dans le nouveau répertoire qui n'avait pas de fichier identique correspondant sur la source. Pour découvrir ce qu'était ce fichier, j'ai relancé rsync en direction de la source:

~% Sudo rsync -av --dry-run my_data_on_60GB_partition/ /media/admin/my_data
sending incremental file list
./
Education_learning_reference/
Education_learning_reference/Business_Education/
Education_learning_reference/Business_Education/Business_education_media_files/
Education_learning_reference/Business_Education/Business_education_media_files/Jeff Hoffman - videos/
Education_learning_reference/Business_Education/Business_education_media_files/Jeff Hoffman - videos/Jeff and David F interview/
Education_learning_reference/Business_Education/Business_education_media_files/Jeff Hoffman - videos/Jeff and David F interview/018 business plans-identifying main KPIs.flv

sent 494,548 bytes  received 1,881 bytes  330,952.67 bytes/sec
total size is 1,900,548,824  speedup is 3,828.44 (DRY RUN)

Une vérification rapide a confirmé qu'il s'agissait du fichier mal formé, où le fichier existait à la fois sur la source et la destination, fichier de destination = 64 Mo, original = 100 Mo. Ce fichier et sa hiérarchie de répertoires appartenaient toujours à root et les autorisations d'origine n'avaient pas encore été restaurées.

Donc en résumé:

  • tous les fichiers que mv jamais atteint sont toujours de retour à leur emplacement d'origine (évidemment)
  • tous les fichiers que mv ont copiés complètement avaient toujours leurs copies originales dans le répertoire source
  • le fichier qui n'était que partiellement copié avait toujours l'original dans le répertoire source

En d'autres termes, tous les fichiers d'origine étaient toujours intacts et la solution dans ce cas était de simplement supprimer le nouveau répertoire!

20
the_velour_fog

Je pensais juste commenter que certaines personnes pourraient être tentées de lancer des "xargs" dans le mix pour faire fonctionner les choses en parallèle. Cela me donne les fous et j'aime vraiment la solution rsync ci-dessus.

En ce qui concerne les éléments du système de fichiers concernant le déplacement et la copie et quand exactement l'original est supprimé, le VFS et les systèmes de fichiers sous-jacents se coordonnent pour garantir l'atomicité par fichier avant de passer à cette étape de suppression. Ainsi, même s'il est interrompu avant l'écriture complète du fichier cible, tout le verrouillage dans le VFS est très strict et protège contre des choses comme l'entrelacement aléatoire des données, même dans des cas parallèles. (J'ai travaillé sur des trucs Linux VFS et NFS4)

L'ajout de "xargs" au mélange aurait probablement fait de l'étape de double vérification de la santé mentale un casse-tête, avec plusieurs fichiers en cours de route. J'aurais aimé avoir plus de script de niveau système. De bons rappels pour moi!

J'ai adoré la question, bon pour les toiles d'araignée, et me fait à nouveau aimer rsync. À votre santé!

4
david richter