find - exec rm vs -delete

260

Estoy tratando de entender la diferencia entre estos dos comandos:

sudo find / -name .DS_Store -delete

y

sudo find / -name ".DS_Store"  -exec rm {} \;

Noté que execse prefiere el método. ¿Por qué? ¿Cuál es más seguro / más rápido / mejor? He usado ambos en mi Macbook y todo parece funcionar bien.

Cebolla
fuente

Respuestas:

245

-delete funcionará mejor porque no tiene que generar un proceso externo para cada archivo coincidente.

Es posible que a -exec rm {} \;menudo se vea recomendado porque -deleteno existe en todas las versiones de find. No puedo comprobarlo ahora, pero estoy bastante seguro de que he usado un findsin él.

Ambos métodos deben ser "seguros".

EDITAR por comentario de @doitmyway: asegúrese de que coincida con el nombre y luego elimine, no al revés (elimine, luego coincida). De lo contrario , se eliminarán todos los archivos, coincidan o no . Es decir, NO hacer esto: find / -delete -name .DS_Store.

Un método común para evitar la sobrecarga de generar un proceso externo para cada archivo coincidente es:

find / -name .DS_Store -print0 | xargs -0 rm

(pero tenga en cuenta que aquí también hay un problema de portabilidad: ¡no todas las versiones de find tienen -print0!)

Celada
fuente
2
Veo. También he leído que usar el -deleteinterruptor antes -nameelimina el árbol de archivos especificado, así que supongo que tengo que tener cuidado.
Cebolla
8
En reciente findpuede utilizar -exec rm {} +para eliminar todos los archivos coincidentes con un solo rmcomando.
jimmij
3
.DS_Storeno contiene ningún carácter especial, por lo que las comillas son innecesarias y no cambian nada en este caso.
Celada
1
Básicamente, solo los espacios en blanco (espacios, tabulaciones, tal vez otros) es lo único que hace que una cadena sin comillas se interprete como dos argumentos de línea de comando separados, pero eso no es todo de lo que tiene que arrepentirse al decidir si desea o no citar. Debe preocuparse por todos los metacaracteres de shell como ;o |o >o <y `` y muchos otros que tienen un significado especial para el shell a menos que se cite.
Celada
1
@MarcoMarsala xargsse ocupa del problema de la lista de argumentos de tamaño limitado de manera transparente al dividirlo en múltiples invocaciones del comando.
Celada
27

Suponiendo que .DS_Storerepresentan archivos y no directorios, la forma más rápida y portátil de hacerlo sería:

sudo find / -name .DS_Store -exec rm {} +

El único riesgo es sudono estar disponible, pero hoy en día es bastante bajo.

La -deleteopción utilizada para exigir la búsqueda de GNU y aún no es estándar en muchas otras findimplementaciones, por lo que no siempre está disponible.

La terminación del comando en +lugar de \;altamente optimiza la execcláusula al no ejecutar el rmcomando para todos y cada uno de los .DS_Storepresentes en el sistema de archivos.

jlliagre
fuente
16

Para una máquina como su macbook, no encontrará mucha diferencia en el rendimiento entre los dos comandos. Sin embargo, si observa la versión -exec, puede ver una sutil diferencia:

sudo find / -iname ".file-to-delete"  -exec rm {} \;

Esto significa que encontrará todos esos archivos con el nombre ".file-to-delete". Sin embargo, esta búsqueda podría devolver algunos falsos positivos no deseados. Al hacer algo con sudo debes ser un poco más cuidadoso. La ventaja de usar -exec rm {} es que puede pasar argumentos a rm como este:

sudo find / -iname "*~"  -exec rm -i {} \;

En este ejemplo, quiero eliminar los archivos de respaldo que emacs crea. Sin embargo, esa tilde podría estar en algún archivo oscuro que no conozco y podría ser importante. Además, quiero confirmar la eliminación. Así que puse la opción '-i' en el comando rm. Esto me dará una eliminación interactiva.

También puede refinar el uso de rm para eliminar directorios y archivos:

find /usr/local/share/ -iname "useless" -exec rm -r {} \;

En resumen, -exec le da un poco más de control sobre el comando real que elimina el elemento encontrado. La ventaja es que utiliza una herramienta para encontrar los archivos, otra herramienta para eliminarlos. Además, no todas las versiones de la utilidad find tienen la opción -delete. Por lo tanto, es mejor usar cada herramienta para su trabajo adecuado. Esta es la filosofía de Unix: una herramienta, un trabajo, úselos juntos para hacer lo que necesita hacer.

El p. John Jenkins
fuente
3
Consulte también -ok rm {} \;en lugar de -exec rm {} \;para confirmación interactiva.
Kusalananda