find -delete non cancella le directory non vuote


32

Il comando

$ find ~ -name .DS_Store -ls -delete

funziona su Mac OS X, ma

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

no: le directory vengono trovate ma non eliminate.

Perché?

PS. So di poterlo fare

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

la domanda è: perché find -delete non non funziona.

Risposte:


36

findLa -deletebandiera funziona in modo simile a rmdirquando si eliminano le directory. Se la directory non è vuota quando viene raggiunta, non può essere eliminata.

Devi prima svuotare la directory. Dal momento che stai specificando -type d, findnon lo farà per te.

Puoi risolverlo facendo due passaggi: prima elimina tutto all'interno delle directory nominate __pycache__, quindi elimina tutte le directory denominate __pycache__:

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

Un po 'meno strettamente controllato, ma in una sola riga:

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

Ciò eliminerà qualsiasi cosa all'interno della tua casa che ha __pycache__come parte del suo percorso.


Alla ricerca 4.4.2, l'ultimo comando deve essere find ~ -path '*/__pycache__*' -delete, o probabilmente find ~ -path '*/__pycache__/*' -o -name __pycache__ -deleteper essere sicuro.
naught101

3
@ naught101, che dovrebbe essere find ~ \( -path '*/__pycache__/*' -o -name __pycache__ \) -deletecome e avere la precedenza su o .
Stéphane Chazelas,

6

Ci sono un paio di potenziali motivi per questo.

1) Gli hai detto di eliminare solo le directory ( -type d) e quelle directory contengono ancora dei file.

2) Le tue directory contengono solo altre directory, quindi -type drisolveranno il problema dei contenuti. Comunque stai usando OS-X, che è in gran parte basato su FreeBSD, e FreeBSD finddi default elaborerà la directory prima del suo contenuto.
Tuttavia -depthesiste l' opzione per risolvere questo problema dicendo finddi elaborare la directory dopo il suo contenuto.

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

Questo problema non esiste su Linux perché l' -deleteopzione abilita implicitamente -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.

2
Sì, ma la ricerca (1) di FreeBSD dice -delete: "... L'elaborazione della prima profondità è implicita da questa opzione", e GNU find (1) dice: "... -delete implica -depth , ...", quindi non dovrebbe essere necessario aggiungere -depthal comando.
G-Man dice "Ripristina Monica" il

1
Dalla findmanpage GNU : "Per evitare confusione, le opzioni globali dovrebbero essere specificate nella riga di comando dopo l'elenco dei punti di partenza, appena prima del primo test, opzione di posizione o azione. Se si specifica un'opzione globale in qualche altro posto, find will emettere un messaggio di avviso che spiega che ciò può essere fonte di confusione ". Ora, -deleteè una "opzione globale" dopo il ~nel comando dato. Ho anche notato che non fa differenza se aggiungi -deptho no. Le directory non vuote non vengono cancellate (ma probabilmente perché lo uso -maxdepthanche io )
David Tonhofer,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.