Necesito eliminar todos los datos compilados:
- directorios llamados
build, - directorios llamados
obj, - * .so archivos.
Escribi un comando
find \( -name build -o -name obj -o -name *.so \) -exec rm -rf {} \;
que recorre todos los directorios de forma recursiva y elimina todo lo que necesito.
¿Por qué tengo esa salida al final? Tal vez debería escribir un comando diferente.
find: `./3/obj': No such file or directory
find: `./3/build': No such file or directory
find: `./1/obj': No such file or directory
find: `./1/build': No such file or directory
find: `./2/obj': No such file or directory
find: `./2/build': No such file or directory

findasífind /search_directory optionsomitir el directorio de búsqueda no es una buena ideaRespuestas:
Use
-pruneen los directorios que va a eliminar de todos modos para decirle quefindno se moleste en tratar de encontrar archivos en ellos:También tenga en cuenta que
*.sodebe citarse, de lo contrario, el shell puede expandirlo a la lista de.soarchivos en el directorio actual.El equivalente de su
-regextipo GNU sería:Tenga en cuenta que si va a usar la sintaxis específica de GNU, también podría usarla en
-deletelugar de-exec rm -rf {} +. Con-delete, GNU sefindenciende-depthautomáticamente. No ejecuta comandos externos, por lo que de esa manera, es más eficiente y también es más seguro, ya que elimina la condición de carrera en la que alguien puede hacer que elimines los archivos incorrectos cambiando un directorio a un enlace simbólico entre el tiempofindencuentra un archivo y lormelimina (verinfo -f find -n 'Security Considerations for find'para más detalles).fuente
-deletetambién maneja mejor cosas como espacios-exec rm -rf {} +que tampoco tiene problemas con ellos.{}, ¿deberían citarse o no? Parece que funciona sin comillas, pero GNU Findutils Manual utiliza,'{}'por ejemplo. ¿Podrías aclararlo por favor?csh, pero nunca pude verificar ese reclamo. No se necesitan en ningún caparazón moderno que yo sepa. Definitivamente no son requeridos por POSIX. Los ejemplos POSIX no los usan.-deleteno se puede usar con directorios.Supongo que la razón es que
findprimero elimina el árbol del directorio e intenta verificar el contenido del directorio, lo que obviamente no es el mejor orden posible. Puede forzarfinda verificar el contenido primero:Debe considerar usar
-deletepara archivos y-exec rmdirdirectorios.fuente
Mi solución.
+ vs \; en el comando -exec
fuente
-exec … {} +ejecuta el comando para múltiples archivos a la vez, tantos como quepan en la línea de comando. Si hay demasiados archivos (o más precisamente si la longitud total de las rutas es demasiado larga),findejecutará múltiples instanciasrmy, por lo tanto, puede terminar eliminando un directorio que está atravesando. Es menos probable con+que con;, pero+no resuelve el problema.