Comment rm -r procède-t-il à la suppression récursive? Dans quel ordre?

30

Y a-t-il un ordre d'opérations rm? J'ai joué rmsur un grand répertoire et je suis curieux de savoir où chercher pour voir ce qui aurait pu être supprimé. Fonctionne-t-il d'abord rmsur les fichiers, puis sur les répertoires? Ou est-il basé sur certaines informations de la table inode?

Spécifications: rm du système GNU coreutils 8.22: Arch Linux fonctionnant sur un système de fichiers beagleboneblack fonctionnant sur était un disque dur externe Seagate (ext4) utilisant USB 2.0.

Backstory:

J'effectuais un nettoyage de répertoire et effectué

cp -r A/ B/ C/ Dest/

Sans le savoir, j'ai suivi cela avec

rm -r A/ B/ C/ Dest/

quand je voulais simplement jouer

rm -r A/ B/ C/

J'ai attrapé cela et j'ai frappé Ctrl+ Cavant que trop longtemps ne soit passé. Plus précisément, c'était moins de 3 secondes car j'utilisais la timecommande en conjonction avec rm& cp. Je suis entré et j'ai examiné en Dest/m'attendant à ce qu'il soit inexistant, mais voilà, il était entier et ne semblait pas être affecté. C'est un peu surprenant car ils A/ B/ C/étaient assez petits. 100 à 200 Mo au total. Dest/cependant, est juste timide de 1 To. L'exécution d'un lssur Dest / a montré qu'il y avait à la fois des fichiers et des répertoires aux deux extrémités de l'alphabet (par exemple AFile.txt.... .... Zoo.txt).

Ai-je eu de la chance et annulé rmavant qu'il ne fasse des ravages sur mon répertoire Dest /? Est-ce rmvraiment si lent (heureusement!)?

Sinon, comment rmprocéder pour supprimer récursivement des choses telles que je devine ce qui aurait pu être perdu?

Je ne m'attends pas vraiment à récupérer ce que j'aurais pu perdre, juste curieux de ce qui a potentiellement été emporté.

N Klosterman
la source

Réponses:

34

rm -rtravaille à tour de rôle sur chacun de ses arguments. Si un argument est un répertoire, il répertorie le répertoire (avec les fonctions opendiret readdirou une méthode équivalente) et opère tour à tour sur chaque entrée. Si une entrée est un répertoire, elle explore cette entrée de manière récursive.

C'est exactement la même méthode que les autres applications utilisent des répertoires de traversée récursive - find, ls -Rfetc.

L'ordre de parcours est imprévisible. Sur la plupart des systèmes de fichiers, l'ordre est reproductible tant qu'aucun fichier n'est ajouté, supprimé ou renommé dans le répertoire (l'ordre pourrait en théorie être complètement aléatoire et changer à chaque fois, mais je ne peux pas penser à un système de fichiers où cela se produit). Sur quelques systèmes de fichiers, l'ordre peut en général être déduit des noms de fichiers ou de l'ordre dans lequel les fichiers ont été créés ou d'une combinaison des deux, mais vous devez connaître les détails du système de fichiers et il peut varier en fonction de la version du pilote. L'ordre de parcours n'est pas quelque chose sur lequel vous pouvez compter.

Notez que lsou echo *triez les fichiers dans l'ordre lexicographique de leurs noms. findet ls -fne triez pas.

La seule chose sur laquelle vous pouvez compter est que les arguments sont traités dans l'ordre. Donc , si C/était encore en partie là, cela signifierait que Dest/n'a pas été touché. S'il C/est parti, vous pouvez avoir une idée de l'endroit où les fichiers ont été supprimés en Dest/vérifiant les heures de modification du répertoire et en les comparant avec l'heure de C/suppression ou l'heure de fin de la copie. Le premier fichier à supprimer pourrait être un fichier directement dans Dest/ou quelque part au fond de la hiérarchie selon que la première entrée dans Dest/celle qui rms'est avérée traverser était un répertoire ou non.

La vitesse rmdépend principalement du nombre de fichiers à supprimer. Il faut un très gros fichier pour avoir un impact notable sur le temps de suppression. La majeure partie du travail consiste à supprimer chaque entrée de répertoire à son tour. Les données du fichier ne sont pas effacées, l'effacement du contenu d'un fichier ne nécessite que de marquer les blocs qu'il utilisait comme libres, ce qui est relativement rapide.

Gilles, arrête de faire le mal
la source
2
L' -foption de lsest documentée comme étant équivalente à -aU, où -asignifie répertorier tous les fichiers et -Usignifie non trié. Je me souviens vaguement d'avoir rencontré une version de lsqui -fne fonctionnait pas (je pense que c'était défini pour être autre chose) mais -aUqui fonctionnait.
G-Man dit `` Réintègre Monica ''
2
@ G-Man POSIX définit -f(comme une extension XSI ); il a en effet d'autres effets au-delà de non triés. Il remonte à V7, donc vous auriez du mal à trouver une implémentation sans elle en dehors, étrangement, de BusyBox. -Ucar non trié est une fonctionnalité GNU, je ne pense pas qu'elle existe ailleurs.
Gilles 'SO- arrête d'être méchant'
Gilles: Existe
Tim
@Tim No. Vous pouvez tester en exécutant ls -Udans un répertoire. Il s'agit du même ordre qui rm -rfonctionnerait dans ce répertoire. Notez que l'ajout ou la suppression d'un fichier peut modifier l'ordre des autres fichiers.
Gilles 'SO- arrête d'être méchant'
Merci. (1) "l'ajout ou la suppression d'un fichier peut changer l'ordre des autres fichiers.", Donc après une suppression partielle accidentelle, ls -Un'aide pas à savoir si les répertoires survivants sont intacts? (2) -U signifie "lister les entrées dans l'ordre du répertoire". -U signifie-t-il l'ordre des entrées du répertoire dans le répertoire?
Tim
5

Comme le dit Gilles, vous ne pouvez généralement pas prédire l'ordre des suppressions dans un répertoire, mais seulement que les répertoires de niveau supérieur seront traités dans l'ordre sur la ligne de commande.

Cependant, vous avez également la garantie qu'il supprimera les hiérarchies de répertoires de bas en haut, car Unix ne permet de supprimer les répertoires que s'ils sont vides. Donc, pour supprimer un répertoire, il doit d'abord tout supprimer. S'il contient des sous-répertoires, il doit d'abord supprimer leur contenu, etc.

Barmar
la source