El final de la expresión primaria se puntuará con un <semicolon> o con un <plus-sign>. Solo un <plus-sign> que sigue inmediatamente a un argumento que contiene solo los dos caracteres "{}" puntuará el final de la expresión primaria. Otros usos del <plus-sign> no se tratarán como especiales. Si la expresión primaria se puntúa con un <punto y coma>, la utilidad nombre_utilidad se invocará una vez para cada nombre de ruta y el primario evaluará como verdadero si la utilidad devuelve un valor cero como estado de salida. Un nombre de utilidad o argumento que contenga solo los dos caracteres "{}" se reemplazará por el nombre de ruta actual. Si un nombre_utilidad o argumentola cadena contiene los dos caracteres "{}", pero no solo los dos caracteres "{}", está definida por la implementación si find reemplaza esos dos caracteres o usa la cadena sin cambios.
Si la expresión primaria se puntúa con un <signo de más>, el primario siempre se evaluará como verdadero, y los nombres de ruta para los que se evalúa el primario se agregarán en conjuntos. La utilidad nombre_utilidad
se invocará una vez para cada conjunto de rutas agregadas. Cada invocación comenzará después de que se agregue el último nombre de ruta en el conjunto, y se completará antes de que salga la utilidad find y antes de que se agregue el primer nombre de ruta en el siguiente conjunto (si corresponde) para este primario, pero no se especifica si la invocación ocurre antes, durante o después de las evaluaciones de otras primarias. Si alguna invocación devuelve un valor distinto de cero como estado de salida, la búsqueda
La utilidad devolverá un estado de salida distinto de cero. Un argumento que contenga solo los dos caracteres "{}" se reemplazará por el conjunto de nombres de ruta agregados, con cada nombre de ruta pasado como un argumento separado a la utilidad invocada en el mismo orden en que se agregó. El tamaño de cualquier conjunto de dos o más nombres de ruta se limitará de modo que la ejecución de la utilidad no provoque que se supere el límite del sistema {ARG_MAX} . Si hay más de un argumento que contiene los dos caracteres "{}", el comportamiento no está especificado.
Cuando el conjunto de longitud del nombre de archivo que encontró excede el sistema ARG_MAX, se ejecuta el comando.
Realicé un experimento usando find / -exec echo | wcy midiendo la relación entre el recuento de caracteres y el recuento de líneas. Encontré que la longitud máxima de la línea de comando utilizada findes significativamente menor que el límite teórico de POSIX, y mucho más cerca de la Size of command buffer we are actually usinglínea en la salida xargs --show-limits. Esto es cierto para Linux y puede ser cierto para la implementación de Mac OS find, aunque xargsno imprimirá el valor en Mac OS. ¿Alguna idea de por qué sucede esto?
pqnet
--show-limitsPOSIX no especifica, la implementación de Mac OS xargsno lo admite. find / -exec echo | wcno funciona Recuerda que ARG_MAXdevuelve bytes. Y es la longitud máxima de los argumentos a las exec(3)funciones.
Cuonglm
Sé --show-limitsque no es POSIX, aunque esta no es la longitud máxima de argumento utilizada por find, que utiliza un valor más pequeño. No entiendo por qué dices que find / -exec echo | wceso no funcionará: en mi opinión, es una buena manera de tener una estimación del valor real (y por lo que puedo ver, mejor que usarlo getconf ARG_MAX). Además, mi sistema de archivos es principalmente, si no todo, caracteres ASCII, por lo que la cantidad de caracteres es aproximadamente la misma que la cantidad de bytes.
pqnet
@pqnet: use find / -exec sh -c 'echo $@ | wc -c' _ {} +isntead.
Cuonglm
lo siento, lo escribí mal, en realidad lo uséfind / -exec echo {} + | wc -lc
pqnet
7
Hay una longitud máxima de la lista de argumentos para un nuevo proceso en el sistema POSIX. finddividirá la ejecución si las rutas de los archivos son más largas que esto. Para ver el límite en Linux, use xargs --show-limits(no funcione en Mac OS, si alguien conoce una alternativa mejor, comente aquí)
editar: robado directamente de la respuesta de Gnouc, la forma POSIX para obtener la longitud máxima de la lista de argumentos es getconf ARG_MAX. Sin embargo, realicé un experimento en mi máquina Mac OS, y parece que findusa un poco más de la mitad de ese número. Esto es coherente con el hecho de que, en el sistema donde funciona, xargs --show-limitsnos dice que no usará la longitud máxima del argumento (en este caso también usará aproximadamente la mitad de ese número), sin embargo, no pude encontrar una explicación para eso.
editar 2: parece que la única forma confiable de determinar cuántos parámetros se findmantendrán unidos para cada invocación es experimentar, por ejemplo ejecutando
find / -exec echo {} + | wc -cl
Como el resultado de findtiene una línea para cada echoinvocación, es posible contarlos usando wc -l. El número total de bytes echoed es la salida de en su wc -clugar. Al dividir uno por otro, obtiene el número promedio de bytes en los parámetros para cada invocación de comando (aunque un valor ligeramente menor, debido al redondeo, aproximadamente la mitad de la longitud promedio de una ruta en su sistema)
xargsno utiliza la longitud máxima de argumento completa porque muchos programas anteponen algunos argumentos adicionales y luego pasan los argumentos a otros programas. Si xargsllena los argumentos al máximo absoluto, dichos programas se rompen, porque no habría espacio para esos argumentos adicionales.
hvd
@hvd tiene sentido. Pero entonces, ¿hay una manera POSIX de saber cuánto de la memoria intermedia es utilizada por xargso find?
pqnet
Puede ejecutarlo con una lista muy larga de argumentos, determinando cuántos argumentos se pasaron en la primera invocación (algo así yes . | xargs | head -n 1 | wc -c) y comparándolos con la salida de getconf ARG_MAX. Pero, al probarlo en mi sistema, la diferencia es tan grande que parece que hay más de lo que sé.
hvd
así que todo se reduce a experimentar ... Actualizaré mi respuesta
find / -exec echo | wc
y midiendo la relación entre el recuento de caracteres y el recuento de líneas. Encontré que la longitud máxima de la línea de comando utilizadafind
es significativamente menor que el límite teórico de POSIX, y mucho más cerca de laSize of command buffer we are actually using
línea en la salidaxargs --show-limits
. Esto es cierto para Linux y puede ser cierto para la implementación de Mac OSfind
, aunquexargs
no imprimirá el valor en Mac OS. ¿Alguna idea de por qué sucede esto?--show-limits
POSIX no especifica, la implementación de Mac OSxargs
no lo admite.find / -exec echo | wc
no funciona Recuerda queARG_MAX
devuelve bytes. Y es la longitud máxima de los argumentos a lasexec(3)
funciones.--show-limits
que no es POSIX, aunque esta no es la longitud máxima de argumento utilizada porfind
, que utiliza un valor más pequeño. No entiendo por qué dices quefind / -exec echo | wc
eso no funcionará: en mi opinión, es una buena manera de tener una estimación del valor real (y por lo que puedo ver, mejor que usarlogetconf ARG_MAX
). Además, mi sistema de archivos es principalmente, si no todo, caracteres ASCII, por lo que la cantidad de caracteres es aproximadamente la misma que la cantidad de bytes.find / -exec sh -c 'echo $@ | wc -c' _ {} +
isntead.find / -exec echo {} + | wc -lc
Hay una longitud máxima de la lista de argumentos para un nuevo proceso en el sistema POSIX.
find
dividirá la ejecución si las rutas de los archivos son más largas que esto. Para ver el límite en Linux, usexargs --show-limits
(no funcione en Mac OS, si alguien conoce una alternativa mejor, comente aquí)editar: robado directamente de la respuesta de Gnouc, la forma POSIX para obtener la longitud máxima de la lista de argumentos es
getconf ARG_MAX
. Sin embargo, realicé un experimento en mi máquina Mac OS, y parece quefind
usa un poco más de la mitad de ese número. Esto es coherente con el hecho de que, en el sistema donde funciona,xargs --show-limits
nos dice que no usará la longitud máxima del argumento (en este caso también usará aproximadamente la mitad de ese número), sin embargo, no pude encontrar una explicación para eso.editar 2: parece que la única forma confiable de determinar cuántos parámetros se
find
mantendrán unidos para cada invocación es experimentar, por ejemplo ejecutandoComo el resultado de
find
tiene una línea para cadaecho
invocación, es posible contarlos usandowc -l
. El número total de bytesecho
ed es la salida de en suwc -c
lugar. Al dividir uno por otro, obtiene el número promedio de bytes en los parámetros para cada invocación de comando (aunque un valor ligeramente menor, debido al redondeo, aproximadamente la mitad de la longitud promedio de una ruta en su sistema)fuente
xargs
no utiliza la longitud máxima de argumento completa porque muchos programas anteponen algunos argumentos adicionales y luego pasan los argumentos a otros programas. Sixargs
llena los argumentos al máximo absoluto, dichos programas se rompen, porque no habría espacio para esos argumentos adicionales.xargs
ofind
?yes . | xargs | head -n 1 | wc -c
) y comparándolos con la salida degetconf ARG_MAX
. Pero, al probarlo en mi sistema, la diferencia es tan grande que parece que hay más de lo que sé.