find -delete löscht keine nicht leeren Verzeichnisse

32

Der Befehl

$ find ~ -name .DS_Store -ls -delete

funktioniert unter Mac OS X, aber

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

nicht - die Verzeichnisse werden gefunden, aber nicht gelöscht.

Warum?

PS. Ich weiß, dass ich das kann

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

die frage ist warum find -delete das nicht geht .

sds
quelle

Antworten:

36

findDas -deleteFlag von funktioniert ähnlich wie rmdirbeim Löschen von Verzeichnissen. Wenn das Verzeichnis bei Erreichen nicht leer ist, kann es nicht gelöscht werden.

Sie müssen zuerst das Verzeichnis leeren. Da Sie spezifizieren -type d, findwerden Sie das nicht für Sie tun.

Sie können dies lösen, indem Sie zwei Durchgänge ausführen: Löschen Sie zuerst alles in den angegebenen Verzeichnissen __pycache__und dann alle angegebenen Verzeichnisse __pycache__:

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

Etwas weniger streng kontrolliert, aber in einer einzigen Zeile:

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

Dies löscht alles in Ihrem Haus, das __pycache__als Teil seines Pfades hat.

GnP
quelle
Nach 4.4.2 muss dieser letzte Befehl sicher sein find ~ -path '*/__pycache__*' -deleteoder wahrscheinlich find ~ -path '*/__pycache__/*' -o -name __pycache__ -deleteauch sein.
Naught101
3
@ naught101, das sein sollte find ~ \( -path '*/__pycache__/*' -o -name __pycache__ \) -deleteals und Vorrang hat über oder .
Stéphane Chazelas
6

Dafür gibt es ein paar mögliche Gründe.

1) Sie haben angegeben, dass nur Verzeichnisse gelöscht werden sollen ( -type d), und in diesen Verzeichnissen befinden sich noch Dateien.

2) Ihre Verzeichnisse enthalten nur andere Verzeichnisse, sodass -type ddas Inhaltsproblem behoben wird. Sie verwenden jedoch OS-X, das größtenteils auf FreeBSD basiert, und FreeBSD findverarbeitet das Verzeichnis standardmäßig vor seinem Inhalt.
Es besteht jedoch die -depthMöglichkeit, dieses Problem zu lösen, indem Sie angeben find, dass das Verzeichnis nach seinem Inhalt verarbeitet werden soll.

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

Dieses Problem tritt unter Linux nicht auf, da die -deleteOption implizit aktiviert wird -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
quelle
2
Ja, aber in FreeBSDs find (1) steht für -delete: "... Die Verarbeitung der tiefsten Durchquerung wird durch diese Option impliziert.", Und GNU find (1) sagt: "... -delete impliziert -depth , ...", also sollte es nicht notwendig sein, um -depthden Befehl hinzuzufügen .
G-Man sagt, dass Monica
1
Aus der GNU- findManpage: "Um Verwirrung zu vermeiden, sollten globale Optionen in der Befehlszeile nach der Liste der Startpunkte unmittelbar vor dem ersten Test, der Positionsoption oder der Aktion angegeben werden. Wenn Sie an einer anderen Stelle eine globale Option angeben, geben Sie find will an eine Warnmeldung ausgeben, die erklärt, dass dies verwirrend sein kann. " Nun -deleteist eine "globale Option" nach dem ~im Befehl angegebenen. Mir ist auch aufgefallen, dass es keinen Unterschied macht, ob Sie hinzufügen -depthoder nicht. Nicht leere Verzeichnisse bleiben nicht gelöscht (aber das liegt wahrscheinlich auch daran, dass ich sie verwende -maxdepth)
David Tonhofer