URL: https://linuxfr.org/users/siltaar/journaux/apres-photorec Title: Après photorec Authors: Siltaär Date: 2025年03月13日T11:11:52+01:00 License: CC By-SA Tags: photorec, réparation, système_de_fichiers, partition et déduplication Score: 76 Ce journal a d'abord été publié sur mon blog technique : https://grimoire.d12s.fr/2023/after_photorec.html#_version_fr Vu qu'on a reparlé de Photorec récemment sur LinuxFr je m'étais noté de pousser ce retour d'expérience ici aussi. # Fichiers perdus Lors du dernier [Repair Café de Pougne-Hérisson](https://www.repaircafe.org/en/cafe/repair-cafe-pougne-herisson/ ) un ami est venu m'apporter un disque dur USB d'1TO en m'expliquant que ce dernier n'était plus reconnu par ces ordinateurs, Windows ou Linux. Matériel défectueux ? Je le branche, il se monte. Ah... l'ami pensait l'avoir testé aussi sous Linux, mais le disque n'échoue à se monter que sous Windows du coup. Bon, bah au moins c'est pas matériel. Je lui montre alors le contenu du disque, il y a 3 dossiers vides (data, storage, work) que l'ami ne reconnait pas. Je lui précise la date de création des dossiers : vendredi dernier à 18h43. Que faisait-il dans la nuit du vendredi en début de soirée ? La mémoire lui revient, la famille voulait enregistrer un film via la nouvelle Box Canal+, or cette dernière réclamait un disque dur pour pouvoir enregistrer quelque chose. Il semble bien que la Box en question a juste formaté le disque qu'on lui présentait (en Ext4) sans prévenir suffisamment explicitement que les données seraient perdues. Le disque n'était donc plus reconnus par les ordinateurs tournant sous Windows... et les fichiers furent joyeusement supprimés par la Box. Bon, après une vérification via testdisk je me retrouvais à lancer photorec. Ça a pris 22h et je me suis retrouvé avec 432 GO de données, en 150 159 fichiers répartis en 238 dossiers. Bien plus que ce que l'ami imaginais avoir comme données. PS: Ce billet peut être vu comme un second épisode après le sauvetage précédent : [Sauver les données d'une partition perdue](https://grimoire.d12s.fr/2018/save_data_from_lost_partitions_on_hard_drive.html#_version_fr). # Et maintenant ? Rendu là, j'aimerai réduire cette masse de fichiers pour aider mon ami à l'explorer et y retrouver son travail récent. (il a d'autres sauvegardes, mais plus anciennes) Lançons tout d'abord un `ncdu` pour voir ce qu'il peut nous en dire : ```console 53.9 GiB [#############] /recup_dir.233 50.1 GiB [############ ] /recup_dir.232 21.2 GiB [##### ] /recup_dir.2 16.7 GiB [#### ] /recup_dir.234 15.9 GiB [### ] /recup_dir.1 13.7 GiB [### ] /recup_dir.229 8.1 GiB [# ] /recup_dir.182 8.1 GiB [# ] /recup_dir.205 6.6 GiB [# ] /recup_dir.180 6.3 GiB [# ] /recup_dir.237 6.1 GiB [# ] /recup_dir.228 5.9 GiB [# ] /recup_dir.227 5.2 GiB [# ] /recup_dir.204 5.2 GiB [# ] /recup_dir.179 5.0 GiB [# ] /recup_dir.224 4.9 GiB [# ] /recup_dir.187 4.7 GiB [# ] /recup_dir.4 4.5 GiB [# ] /recup_dir.3 4.2 GiB [# ] /recup_dir.186 4.1 GiB [ ] /recup_dir.222 4.0 GiB [ ] /recup_dir.215 [...] Total disk usage: 431.7 GiB Apparent size: 428.6 GiB Items: 150 159 ``` Je peux confirmer ce nombre de fichiers via : ```console $ rg -uuu --files --iglob * | wc -l 149682 $ python -c 'print(149682+(238*2))' # adding folders 150158 <1> ``` `<1>` Il semble que chaque dossier compte pour 2 items (tels que les compte `ncdu`), et encore il en manque toujours 1... # Retirer les fichiers de programmation En explorant quelques dossiers, je constate qu'il y a beaucoup de fichiers C et Python parmi les fichiers récupérés. Combien exactement ? ```console $ rg -uuu --files --iglob "*.c" Recup | wc -l <1> 21348 # Nombre de fichiers Pythons : $ rg -uuu --files --iglob "*.py" Recup | wc -l 4363 ``` `<1>` `photorec` était configuré pour écrire dans le dossier `Recup` Bon, alors je peux créer un dossier "poubelle" et y déclarer ces fichiers, mon amis n'est pas un programmeur. ```console $ mkdir poubelle $ for a in `seq 238`; do mkdir "poubelle/recup_dir.$a"; done; <1> $ rg -uuu --files --iglob "**py" . | xargs -I {} mv {} poubelle/{} <2> ``` `<1>` Création de 238 sous dossiers dans "poubelle" folder. `<2>` Déplacement des fichiers Python. Mais combien y a-t-il de langages de programmation représentés ? ```console $ for a in `rg --type-list | cut -f 1 -d ':'`; do echo "$a: `rg --files -t $a | wc -l`"; done; <1> ``` `<1>` Pour chaque type de fichier reconnu par `rg` (169 en l'occurrence) afficher le nombre de fichier qu'rg peut en compter ``` fortran: 14 <1> h: 1642 html: 292 java: 219 config: 3 pdf: 14536 perl: 12 php: 9 sh: 11 svg: 377 txt: 8645 ``` `<1>` Je n'ai gardé là que les types effectivement présents Tiens, ça liste également des PDF mais pas d'ODT et puis on a pas les extensions fichiers exactes pour chaque type... # Compter les fichiers par type Lançons nous dans un meilleur aperçu de la répartition des fichiers par type, en comptant les fichiers par type mime et par extension (du moins celle que `photorec` a attribué aux fichiers). ```console $ rg -uuu --files --iglob "*" Recup> 122552_filenames.txt <1> ``` `<1>` J'en étais encore à 122552 fichiers. La commande dura 15s. ## Compter les fichiers dont le noms a été retrouvé ```console $ rg '.{42,}' 122552_filenames.txt> liste_fichiers_avec_nom.txt $ wc -l liste_fichiers_avec_nom.txt 4566 <1> ``` `<1>` Cela représente 3,7% des 122k fichiers restant Voici quelques exemples de long nom de fichier à éviter quand même : - Recup/recup_dir.10/f136265448.sqlite - Recup/recup_dir.194/f936769224_ftyp.mov - Recup/recup_dir.36/f179430256_PAY18E.pdf *** Listons maintenant tous les fichiers par type mime et par extension : ```console $ file --mime-type -f 122552_filenames.txt> 122552_file_mime-types.txt <1> $ sed -r 's/\s+/ /g' ../122552_file_mime-types.txt | cut -f 3,4,5,6,7 -d '.' | sort | uniq -c | sort -r -n> ../122552_file_ext_mime-type_summary.txt <2> ``` `<1>` Bon là ça prend 2h sur ce disque dur à plateau d'une grande marque et relativement moderne `<2>` Cette ligne retire des espaces dans chaque ligne, puis retire le début de chaque ligne (jusqu'au 2e point), puis tri le fichier et compte les lignes identiques avant de les trier par nombre d'occurrences. ``` 72429 jpg: image/jpeg 14544 pdf: application/pdf 7513 txt: text/plain 6576 png: image/png 5198 odt: application/vnd.oasis.opendocument.text 3430 mpg: video/mpeg 1795 avi: video/x-msvideo 1369 elf: application/x-sharedlib 1219 mp3: audio/mpeg 1199 apple: application/octet-stream 739 txt: application/octet-stream [...] <1> ``` `<1>` Il y avait encore 77 types de fichiers à ce moment là (après le retrait des fichiers C, H, Python, Java et quelques autres). On note qu'il est intéressant de retirer les fichiers `elf` et `apple` mais que le gros morceau reste les `jpg`. ## Ranger les fichiers par extension Un ami a utilisé ce billet de blog pour récupérer des fichiers perdus dans un Windows 11 sur support de stockage NVME. Il a décidé de s'arrêter à cette étape, après avoir rangé les 10k fichiers par extension. Voilà le script qu'il a utilisé : ```bash #!/bin/bash # Utilisation du premier argument comme répertoire source source_dir="1ドル" if [ -z "$source_dir" ]; then echo "Usage: 0ドル " exit 1 fi # Fonction récursive pour traiter les fichiers d'un répertoire process_directory() { local dir="1ドル" for ext in $(find "$dir" -type f | sed -n 's/.*\.\(.*\)/1円/p' | sort -u); do ext_dir="${ext}_files" # Création du répertoire d'extension s'il n'existe pas déjà mkdir -p "$ext_dir" # Déplacer les fichiers de l'extension vers le répertoire d'extension find "$dir" -type f -wholename "*.$ext" -exec mv {} "$ext_dir" \; done } # Appel initial pour le répertoire source process_directory "$source_dir" ``` # Supprimer les miniatures JPEG Explorer un dossier au hasard pour voir ce qu'il contient comme images : ```console $ find . -name "*.jpg" | wc -l 89 find . -name "*.jpg" -size -35k | wc -l 68 find . -name "*.jpg" -size -50k | wc -l 69 find . -name "*.jpg" -size -100k | wc -l 71 find . -name "*.jpg" -size -150k | wc -l 78 find . -name "*.jpg" -size -1500k | wc -l 78 find . -name "*.jpg" -size -1800k | wc -l 79 ``` On constate qu'il y a plein de petites images, principalement des miniatures de vraies photos, créées par divers logiciels (explorateur de fichier, visionneur de photo...) sur divers systèmes d'exploitation. On remarque également qu'il y a un grand trou dans la répartition des images entre 150ko et 1500ko. Les photos plus grosses auront toutes les chances d'être des vraies. Pour ma part j'ai décidé de couper à `300ko` : ```console find Recup -name "*.jpg" -size -300k | wc -l 43414 find Recup -name "*.jpg" -size -300k | xargs -I {} mv {} poubelle/{} <1> ``` `<1>` Cela prend environ 1 minute Arrivé là on en est à 72635 fichiers et 414 GO soit 50% du nombre de fichiers du départ mais toujours 96% de l'occupation disque. # fclones pour trouver les fichiers redondants J'ai alors décidé d'essayer [fclones](https://grimoire.d12s.fr/2020/find_duplicate_files.html) pour tenter de trouver des fichiers qui seraient présents en plusieurs exemplaires parmi les fichiers restants. ```console $ fclones group --cache /tmp> /tmp/fclones.group.txt <1> <2> fclones: info: Found 48416 (149.9 GB) redundant files $ fclones move poubelle < /tmp/fclones.group.txt Deduplicating 17252 groups fclones: info: Processed 48416 files and reclaimed 149.9 GB space <3> <4> ``` `<1>` L'option `--cache` permet de sauver l'index des hash de fichier sur le disque dur (ici rangé dans le dossier `/tmp`), cela permettrait de le réutiliser si on avait à relancer la commande rapidement suite à une erreur, sans avoir à recalculer tous les hash `<2>` L'execution a pris 2h38 `<3>` Cette dernière phase a pris 10 min `<4>` Il aurait probablement été préférable de faire des liens symboliques avant de déplacer les fichiers redondants Nous voilà rendus à 24220 fichiers et 273 GO soit 16% du nombre initial de fichiers et 63% de la taille considérée. # Retrait des dossiers vides Une partie rapide : ```console $ rmdir Recup/* $ exa -l | wc -l 199 <1> ``` `<1>` Donc 39 dossiers vides retirés (16%) # Retrouver les fichiers récents Malheureusement `photorec` ne sait pas restaurer toutes les dates de création de fichier (mais, comme pour les noms, seulement celles retrouvables dans les métadonnées internes d'un fichier). Quand la date est inconnue, c'est la date du jour qui est utilisée. Un tiers des documents ont pu être éliminés comme étant trop vieux (plus de 4 mois). Voici la commande utilisée pour retrouver les fichiers récents : ```console $ find . -newermt $(date +%Y-%m-%d -d '4 months ago') -type f -print> recent_file_list.txt <1> <2> ``` `<1>` Retrouver les fichiers qui ont moins de 4 mois `<2>` Environ 100k fichiers furent trouvés par les 150k du départ On peut retirer de cette liste les fichiers datant du jour de la récupération pour une liste plus courte (et donc plus facile à consulter) : ```console $ find . -newermt $(date +%Y-%m-%d -d '4 months ago') ! -newermt $(date +%Y-%m-%d -d '1 week ago') -type f -print> liste_incomplete_fichiers_recents.txt <1> ``` `<1>` Là on tombe à 453 fichiers ; 4 ODT ; 0 avec son nom d'origine Vu que je suis reparti de la liste intégrale des fichiers, on peut en retirer tous les fichiers éliminés ou dédoublonnés : ```console $ for a in `cat ~/liste_des_fichiers_recents.txt` ; do if test -f $a; then echo $a>> ~/liste_des_fichiers_recents_existants.txt ; fi; done ``` On en arrive à 17 122 fichiers, dont 144 DOC, 76 ODT... # Conclusion `photorec` est un outil très précieux mais il n'est pas facile de s'y retrouver dans tous les fichiers qu'il retrouve. Dans ce billet, nous sommes passés de 150k à 17k fichiers récents et uniques retrouvés. Nous avons vu que `photorec` peut vous aider à retrouver votre précieux rapport perdu sur un support mourant, mais il risque de le retrouver plusieurs fois, accompagné de toutes ses versions précédentes et/ou supprimées... vos photos serons sauvées, mais également leurs miniatures et même avec toutes les techniques illustrées ici pour raffiner les données récupérées, il vous faudra encore beaucoup de travail pour vous réapproprier cette montagne de fichiers ## Pensées pour la prochaine fois J'aurais pu commencer par faire une copie bit à bit du support via `dd` pour pouvoir éventuellement revenir à une étape précédente en cas de fausse manip.

AltStyle によって変換されたページ (->オリジナル) /