Entiendo que la -exec puede aceptar una + opción para imitar el comportamiento de xargs. ¿Hay alguna situación en la que prefiera una forma sobre la otra?

Yo personalmente tiendo a preferir la primera forma, aunque solo sea para evitar el uso de una tubería. Me imagino que seguramente los desarrolladores de find debe» haber realizado las optimizaciones adecuadas. ¿Estoy en lo cierto?

Responder

Es posible que desee encadenar llamadas para encontrar (una vez, cuando aprendió, que es posible , que podría ser hoy). Esto, por supuesto, solo es posible mientras permanezca en la búsqueda. Una vez que canaliza a xargs, está fuera de alcance.

Pequeño ejemplo, dos archivos a.lst y b.lst:

cat a.lst fuddel.sh fiddel.sh cat b.lst fuddel.sh 

No hay truco aquí – simplemente el hecho de que ambos contienen «fuddel» pero solo uno contiene «fiddel».

Supongamos que no lo sabíamos. Buscamos un archivo que cumpla 2 condiciones:

find -exec grep -q fuddel {} ";" -exec grep -q fiddel {} ";" -ls 192097 4 -rw-r--r-- 1 stefan stefan 20 Jun 27 17:05 ./a.lst 

Bueno, tal vez conozca la sintaxis de grep u otro programa para pasar ambas cadenas como condición, pero eso » Ese no es el punto. Todos los programas que pueden devolver verdadero o falso, dado un archivo como argumento, se pueden usar aquí; grep fue solo un ejemplo popular.

Y tenga en cuenta que puede seguir find -exec con otros comandos de búsqueda, como -ls o -delete o algo similar. Tenga en cuenta que eliminar no solo hace rm (elimina archivos), sino rmdir (elimina directorios) también.

Dicha cadena se lee como una combinación Y de comandos, siempre que no se especifique lo contrario (es decir, con un -or modificador (y parens (que necesitan enmascaramiento))).

Así que no saldrá de la cadena de búsqueda, lo cual es útil. No veo ninguna ventaja en el uso de -xargs, ya que debe tener cuidado al pasar los archivos, que es algo que find no necesita hacer – automáticamente maneja pasar cada archivo como un único argumento para usted.

Si cree que necesita un enmascaramiento para los hallazgos {} llaves , no dude en visitar mi pregunta que solicita pruebas. Mi afirmación es: No es así.

Comentarios

  • Esta publicación me ha abierto los ojos a una nueva forma de usar find. ¡Muchas gracias!
  • » No ‘ no veo ninguna ventaja en el uso -xargs «. ¿Cuál ‘ es la -exec forma de hacer xargs -P4 para que tres de los cuatro núcleos no ‘ permanezcan inactivos.
  • @DamianYerrick: Finalice el comando -exec no en «; » pero con un + (/ signo más).

Responder

La canalización segura de nombres de archivos a xargs requiere que su find admita -print0 y tu xargs tiene la opción correspondiente para leerla (--null o -0). De lo contrario, los nombres de archivo con unprintab Los caracteres le, las barras invertidas, las comillas o los espacios en blanco en el nombre pueden causar un comportamiento inesperado. Por otro lado, find -exec {} + está en la POSIX find especificación , por lo que es portátil y tan seguro como find -print0 | xargs -0, y definitivamente más seguro que find | xargs. Recomiendo nunca hacer find | xargs sin -print0.

Comentarios

  • Una excepción notable a la portabilidad de find … -exec … {} + es OpenBSD, que solo adquirió esta función con la versión 5.1 lanzada en 2012. Todos los BSD han tenido -print0 durante varios años, incluso OpenBSD (aunque también resistió esa función durante un tiempo). Solaris, por otro lado, se adhiere a las funciones POSIX, por lo que obtiene -exec + y no -print0.
  • -print0 es una molestia y, aunque puedes discutir xargs --delimiter "\n" no es ‘ t equivalente, yo ‘ nunca he usado el primero después de descubrir el segundo .
  • No ‘ no veo cómo -0 es más doloroso que --delimiter "\n".
  • Además de -0, GNU xargs necesita -r para evitar ejecutar el comando si ‘ no hay entrada.
  • Otro problema de | xargs -r0 cmd es que cmd ‘ s stdin se ve afectado (según la xargs implementación, ‘ s /dev/null o la tubería.

Responder

Si usa el formulario -exec ... ; (recordando para escapar del punto y coma), estás ejecutando el comando una vez por nombre de archivo. Si usas -print0 | xargs -0, ejecutas varios comandos por nombre de archivo. Definitivamente debes usar el -exec +, que coloca varios archivos en una sola línea de comando y es mucho más rápido cuando se trata de una gran cantidad de archivos.

Una gran ventaja de usar xargs es la capacidad de ejecutar varios comandos en paralelo utilizando xargs -P. En sistemas de varios núcleos, eso puede proporcionar un gran ahorro de tiempo.

Comentarios

  • Quisiste decir -P en lugar de -p. Tenga en cuenta que xargs -P no está en el estándar POSIX, mientras que find -exec {} + sí, lo cual es importante si busca portabilidad.
  • @Alexios No ‘ no tiene que escapar del signo más, porque no tiene un significado especial para el shell: find /tmp/ -exec ls "{}" + funciona bien.
  • Corrent, por supuesto. ‘ he estado escapando de todo después del -exec durante tanto tiempo (soy ‘ masoquista , No ‘ ni siquiera uso comillas para escapar {}, siempre escribo \{\}; don ‘ t ask), todo parece que debe escaparse ahora.
  • @Alexios: Si encuentra un ejemplo (excepto por ser masoquista) donde el el enmascaramiento de las llaves es útil, por favor bríndelo como una respuesta a mi pregunta aquí – afaik, esta sugerencia está desactualizada y solo es una reliquia en la página de manual. ‘ nunca he visto un ejemplo en el que find /tmp/ -exec ls {} + no ‘ no funcione.
  • Para mí, esta es la memoria muscular formada en los días de SunOS 4. Desde que ‘ lo he estado haciendo durante años, no me di cuenta de cuándo bash comenzó a aceptar las llaves textualmente. Estoy ‘ bastante seguro de que al menos una de las viejas conchas que ‘ he usado arrojaba ataques sibilantes si los tirantes no eran ‘ t escapó.

Respuesta

Con respecto al rendimiento, pensé que -exec … + sería simplemente mejor porque «es una única herramienta que hace todo el trabajo, pero una parte de la documentación de GNU findutil» dice que -exec … + podría ser menos eficiente en algunos casos:

[buscar con -exec … +] puede ser menos eficiente que algunos usos de xargs; por ejemplo, xargs permite crear nuevas líneas de comando mientras el comando anterior aún se está ejecutando, y le permite especificar una cantidad de comandos para que se ejecuten en paralelo. Sin embargo, la construcción find ... -exec ... + tiene la ventaja de una amplia portabilidad. GNU findutils no admitía ‘-exec ... +’ hasta la versión 4.2.12 [enero de 2005] ; una de las razones de esto es que ya tenía la acción «-print0» en cualquier caso.

No estaba exactamente seguro de lo que eso significaba, así que pregunté en el chat dónde derobert lo explicó como:

find probablemente podría continuar buscando el siguiente lote de archivos mientras el -exec … + se está ejecutando, pero no «t.
find … | xargs … lo hace, porque entonces la búsqueda es un proceso diferente y se mantiene ejecutándose hasta que el búfer de la tubería se llene

(Formateando por mí)

Así que ahí está. Pero si el rendimiento realmente importa, tendría que hacer una evaluación comparativa realista o incluso preguntarse si le gustaría usar shell para tales casos.

Aquí, en este sitio, creo que es mejor aconsejar a la gente que use el formulario -exec … + siempre que sea posible porque solo porque es más simple y por las razones mencionadas en las otras respuestas aquí (por ejemplo, manejar nombres de archivos extraños sin tener que pensar mucho).

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *