find -delete ne supprime pas les répertoires non vides

32

La commande

$ find ~ -name .DS_Store -ls -delete

fonctionne sur Mac OS X, mais

$ find ~ -name __pycache__ -type d -ls -delete

non - les répertoires sont trouvés mais pas supprimés.

Pourquoi?

PS Je sais que je peux faire

$ find ~ -name __pycache__ -type d -ls -exec rm -rv {} +

la question est pourquoi find -delete ne fonctionne pas .

sds
la source

Réponses:

36

findL' -deleteindicateur fonctionne comme rmdirlors de la suppression de répertoires. Si le répertoire n'est pas vide lorsqu'il est atteint, il ne peut pas être supprimé.

Vous devez d'abord vider le répertoire. Puisque vous spécifiez -type d, findne le fera pas pour vous.

Vous pouvez résoudre ce problème en faisant deux passes: supprimez d'abord tout ce qui se trouve dans les répertoires nommés __pycache__, puis supprimez tous les répertoires nommés __pycache__:

find ~ -path '*/__pycache__/*' -delete
find ~ -type d -name '__pycache__' -empty -delete

Un peu moins étroitement contrôlé, mais sur une seule ligne:

find ~ -path '*/__pycache__*' -delete

Cela supprimera tout ce qui se trouve dans votre maison et qui fait __pycache__partie de son chemin.

GnP
la source
Sur la découverte 4.4.2, cette dernière commande doit être find ~ -path '*/__pycache__*' -delete, ou probablement find ~ -path '*/__pycache__/*' -o -name __pycache__ -deleteêtre sûre.
naught101
3
@ naught101, qui doit être find ~ \( -path '*/__pycache__/*' -o -name __pycache__ \) -deleteas et a priorité sur ou .
Stéphane Chazelas
6

Il y a plusieurs raisons possibles à cela.

1) Vous lui avez dit de supprimer uniquement les répertoires ( -type d), et ces répertoires contiennent toujours des fichiers.

2) Vos répertoires ne contiennent que d'autres répertoires, donc le -type ds'occupera du problème de contenu. Cependant, vous utilisez OS-X, qui est largement basé sur FreeBSD, et FreeBSD findpar défaut traitera le répertoire avant son contenu.
Cependant, l' -depthoption existe pour résoudre ce problème en disant findde traiter le répertoire après son contenu.

find ~ -name __pycache__ -type d -ls -delete -depth

Ce problème n'existe pas sur Linux car l' -deleteoption est implicitement activée -depth.

 

FreeBSD man 1 find:

 -depth  Always true; same as the non-portable -d option. Cause find to
   perform a depth-first traversal, i.e., directories are visited in
   post-order and all entries in a directory will be acted on before
   the directory itself. By default, find visits directories in
   pre-order, i.e., before their contents. Note, the default is not
   a breadth-first traversal.

GNU man 1 find:

 -depth Process each directory's contents before the directory itself. The -delete
        action also implies -depth.
Patrick
la source
2
Oui, mais la découverte de FreeBSD (1) dit pour -delete, "... Le traitement de traversée en profondeur d'abord est impliqué par cette option.", Et GNU find (1) dit, "... -delete implique -depth , ...", donc il ne devrait pas être nécessaire d'ajouter -depthà la commande.
G-Man dit `` Réintègre Monica ''
1
Depuis la findpage de manuel GNU : "Pour éviter toute confusion, les options globales doivent être spécifiées sur la ligne de commande après la liste des points de départ, juste avant le premier test, l'option positionnelle ou l'action. Si vous spécifiez une option globale à un autre endroit, find will émettre un message d'avertissement expliquant que cela peut prêter à confusion. " Maintenant, -deleteest une "option globale" après la ~dans la commande donnée. J'ai également remarqué que cela ne fait aucune différence que vous ajoutiez -depthou non. Les répertoires non vides restent non supprimés (mais c'est probablement parce que j'en utilise -maxdepthaussi)
David Tonhofer