Pourquoi la récursivité ne monte-t-elle pas avec rm?

13

Je m'interroge sur la direction de la récursivité en général et rm en particulier.

rm récursion ne fonctionne que vers le bas correct?

En cours d'exécution: sudo rm -R *.QTFSsupprimera tous les fichiers * .QTFS du répertoire actuel et ses enfants, correct?

le répertoire actuel affiché par ls -lhacontient également .et des ..liens pour l'absence d'un meilleur mot, alors pourquoi la récursivité ne suit-elle pas ces liens vers le haut dans l'arborescence des répertoires? Y a-t-il une limite artificielle à l'application rm, ou .et ce ..ne sont pas des choses réelles?


la source
5
Parce que la racine et la folie, c'est comme ça ...
jasonwryan
1
Eh bien, pour une anecdote intéressante ... J'ai exécuté rm -rf sur certains sous-répertoires à la recherche innocente à un moment donné seulement pour découvrir à mon horreur qu'un utilisateur avait lié des choses en dur à un très important en amont, que rm a ensuite mangé. Oui, j'avais des sauvegardes en cours et aucune donnée n'a été perdue, mais que ce soit un récit édifiant ... :-)
Brian Knoblauch
@BrianKnoblauch, quel mal pourrait être fait en supprimant un lien dur? Je n'ai pas compris votre histoire ...
Alexey
@Alexey Le fait est que le lien dur lui-même n'a pas été supprimé. Il est revenu dans le répertoire lié dur, qui était lié à un point plus élevé du système de fichiers, alors a commencé à manger les données de tout le monde ...
Brian Knoblauch

Réponses:

18

rm la récursivité ne fonctionne que vers le bas correct?

rm -r x ysupprimera xet yet tout ce qui s'y trouve (s'il s'agit de répertoires), mais pas leurs parents ou quoi que ce soit en dehors d'eux.

En cours d'exécution: sudo rm -R *.QTFSsupprimera tous les fichiers * .QTFS du répertoire actuel et ses enfants, correct?

Non. Il supprimera tous les fichiers nommés *.QTFS, tous les fichiers récursivement dans les répertoires appelés *.QTFSet ces répertoires eux-mêmes. Si vous souhaitez cet autre comportement de suppression, utilisez find -delete.

le répertoire actuel affiché par ls -lhacontient également .et des ..liens pour l'absence d'un meilleur mot, alors pourquoi la récursivité ne suit-elle pas ces liens vers le haut dans l'arborescence des répertoires? Y a-t-il une limite artificielle à l'application rm, ou .et ce ..ne sont pas des choses réelles?

C'est une limite artificielle de rm.

Ce n'est pas vraiment artificiel, c'est la seule façon dont cela pourrait fonctionner. Si rmles ..liens parents étaient suivis , chacun rm -rsupprimerait tous les fichiers du système, en suivant tous les ..liens jusqu'au bout /. rmvoit les entrées ..et .dans chaque répertoire lorsqu'il répertorie le contenu et les ignore explicitement pour cette raison.

Vous pouvez l'essayer vous-même, en fait. Exécutez rm -r .et la plupart des rmimplémentations refuseront d'agir, signalant explicitement une erreur:

$ rm -r .
rm: refusing to remove ‘.’ or ‘..’ directory: skipping ‘.’

(ce message vient de GNUrm ; d'autres sont similaires). Lorsqu'il rencontre ces entrées implicitement, plutôt que comme arguments explicites, il les ignore simplement et continue. Ce comportement est requis par POSIX . Dans GNU rmet dans de nombreux BSD, il est fourni automatiquement par la fts_readfamille de fonctions de traversée de hiérarchie.

ou .et ..ne sont pas de vraies choses?

.et ..sont généralement de véritables entrées de répertoire, bien que cela soit spécifique au système de fichiers. Ils seront presque toujours présentés comme s'ils étaient de véritables entrées pour tout le code utilisateur, indépendamment. De nombreux logiciels (et pas seulement rm) mettent en évidence leur comportement afin d'attraper ou d'empêcher une récursion incontrôlée ou indésirable.

Michael Homer
la source
Pour ceux qui recherchent des preuves (ou tout simplement intéressés), regardez comment cela est implémenté dans GNU coreutils .
Chris Hayes
@ChrisHayes Le lien gitweb équivalent est dans la réponse. Le cas récursif réel se trouve dans l' fts_readimplémentation, cependant, celui-ci est juste pour les arguments de ligne de commande.
Michael Homer
@MichaelHomer Oh wow, il en est ainsi. Cette couleur de lien ne se démarque pas sur ce schéma SE. Mon erreur.
Chris Hayes
2
Cette réponse est correcte mais aussi un peu imprécise. rmne voit même pas, *.QTFScar il est étendu dans les noms de fichiers par bash avant que le binaire rm soit appelé. La réponse de @ tobyink le note.
Daenyth
En tant que sidenote, ces comportements .et ..les cas particuliers seraient à l'origine de l'existence des
fichiers dot
5

En plus de ce que Michael Homer a écrit, il y a un autre facteur qui rend difficile la récurrence accidentelle dans le répertoire parent.

Allez dans votre répertoire personnel et tapez quelque chose comme:

echo *s*

Vous verrez qu'il affiche une liste de fichiers et de répertoires contenant la lettre "s". Cependant, aucun fichier commençant par un point de tête n'est affiché. Pour les montrer, vous pouvez utiliser:

echo .*s*

En effet, le shell refuse de s'étendre *pour englober un point de tête. Cela signifie que:

rm -fr *

Ne rentre pas ...

tobyink
la source