(3 respuestas)
Cerrado hace 2 años.
Contexto de la pregunta:según las especificaciones de POSIX, ARG_MAX es la longitud máxima de argumentos de línea de comandos a exec()
familia de funciones. Lo que me lleva a creer que ese es el número real de argumentos, sin embargo, eso claramente no funcionó:
$ ulimit -s
8192
$ touch {1..18000}.jpg
$ rm *.jpg
$
Claramente, esto funciona bien, a pesar de tener una longitud de más de 8192 elementos. Según la respuesta de D.W., el 8192
es supuestamente el tamaño en kB. Claramente, la suposición anterior estaba equivocada.
Aquí es donde entra la pregunta real:¿Cómo calculo la cantidad de elementos que realmente serán superar el límite de 8192 kB? En otras palabras, qué tipo de cálculo debo realizar para garantizar que *.jpg
tipo de glob resultará en Argument list too long
error?
Tenga en cuenta que esto no es un duplicado de lo que define el tamaño máximo del argumento de un solo comando. Conozco getconf ARG_MAX
y ulimit -s
valores, esa no es mi pregunta. Necesito saber cómo generar suficientes argumentos en tamaño que estarán por encima del límite . En otras palabras, necesito encontrar una forma de obtener el error, no de evitarlo.
Respuesta aceptada:
Usando getconf ARG_MAX
para generar una larga lista de x
y llamar a una utilidad externa con eso como argumento generaría un error de "Lista de argumentos demasiado larga":
$ /bin/echo $( perl -e 'print "x" x $ARGV[0]' "$(getconf ARG_MAX)" )
/bin/sh: /bin/echo: Argument list too long
El entorno y la longitud de la cadena /bin/echo
se incluirá en lo que hace que ocurra el error, por lo que podemos tratar de encontrar el número más grande posible restando estos:
$ env
PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11R6/bin:/usr/local/bin
(Comencé este shell con env -i sh
, por lo que solo existe el PATH
variable en el entorno)
$ /bin/echo $( perl -e 'print "x" x ($ARGV[0] - length($ENV{"PATH"}) - length("/bin/echo"))' "$(getconf ARG_MAX)" )
sh: /bin/echo: Argument list too long
Todavía demasiado tiempo. ¿Por cuánto?
i=0
while ! /bin/echo $( perl -e 'print "x" x ($ARGV[0] - length($ENV{"PATH"}) - length("/bin/echo") - $ARGV[1])' "$(getconf ARG_MAX)" "$i" )
do
i=$(( i + 1 ))
done
Este ciclo sale para i=8
.
Entonces, hay cuatro bytes que no puedo contabilizar de inmediato (cuatro de los ocho deben ser para el nombre del PATH
Variable ambiental). Estos son los terminadores nulos para las cuatro cadenas PATH
, el valor de PATH
, /bin/echo
y la cadena larga de x
personajes.
Tenga en cuenta que cada el argumento termina en nulo, por lo que cuantos más argumentos tenga para el comando, más corta puede ser la longitud combinada de ellos.
Además, solo para mostrar el efecto de un gran entorno:
$ export BIG=$( perl -e 'print "x" x $ARGV[0]' "$( getconf ARG_MAX )" )
$ /bin/echo hello
sh: /bin/echo: Argument list too long
$ /bin/echo
sh: /bin/echo: Argument list too long