find -delete no elimina directorios no vacíos

32

El comando

$ find ~ -name .DS_Store -ls -delete

funciona en Mac OS X, pero

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

no: los directorios se encuentran pero no se eliminan.

¿Por qué?

PD. Se que puedo hacer

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

la pregunta es ¿por qué find -delete no no trabajar.

sds
fuente

Respuestas:

36

findLa -deletebandera de funciona de manera similar a rmdircuando se eliminan directorios. Si el directorio no está vacío cuando se alcanza, no se puede eliminar.

Primero debe vaciar el directorio. Como está especificando -type d, findno lo hará por usted.

Puede resolver esto haciendo dos pases: primero elimine todo dentro de los directorios nombrados __pycache__, luego elimine todos los directorios nombrados __pycache__:

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

Algo menos estrictamente controlado, pero en una sola línea:

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

Esto eliminará cualquier cosa dentro de su hogar que tenga __pycache__como parte de su camino.

GnP
fuente
En find 4.4.2, ese último comando debe ser find ~ -path '*/__pycache__*' -delete, o probablemente find ~ -path '*/__pycache__/*' -o -name __pycache__ -deletesea ​​seguro.
naught101
3
@ naught101, que debería ser find ~ \( -path '*/__pycache__/*' -o -name __pycache__ \) -deletecomo y tiene prioridad sobre o .
Stéphane Chazelas
6

Hay un par de posibles razones para esto.

1) Le dijiste que eliminara solo directorios ( -type d), y esos directorios todavía tienen archivos dentro de ellos.

2) Sus directorios solo contienen otros directorios, por lo que -type dse ocupará del problema de contenido. Sin embargo, está utilizando OS-X, que se basa principalmente en FreeBSD, y FreeBSD findprocesará el directorio antes que su contenido de manera predeterminada.
Sin embargo -depth, existe la opción de resolver este problema diciéndole findque procese el directorio después de su contenido.

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

Este problema no existe en Linux porque la -deleteopción habilita implícitamente -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.
Patricio
fuente
2
Sí, pero el hallazgo de FreeBSD (1) dice -delete: "... El procesamiento transversal de profundidad primero está implícito en esta opción", y GNU find (1) dice: "... -delete implica -profundidad , ...", por lo que no debería será necesario agregar -depthal comando.
G-Man dice 'reinstalar a Monica' el
1
De la página de findmanual de GNU : "Para evitar confusiones, las opciones globales deben especificarse en la línea de comandos después de la lista de puntos de inicio, justo antes de la primera prueba, opción posicional o acción. Si especifica una opción global en otro lugar, find will emitir un mensaje de advertencia explicando que esto puede ser confuso ". Ahora, -deletees una "opción global" después ~del comando dado. También he notado que no importa si agregas -deptho no. Los directorios no vacíos permanecen sin borrar (pero eso es probablemente porque yo -maxdepthtambién los uso )
David Tonhofer