Tenía la impresión de que la longitud máxima de un solo argumento no era el problema aquí, sino el tamaño total de la matriz de argumentos general más el tamaño del entorno, que se limita a ARG_MAX
. Por lo tanto, pensé que algo como lo siguiente tendría éxito:
env_size=$(cat /proc/$$/environ | wc -c)
(( arg_size = $(getconf ARG_MAX) - $env_size - 100 ))
/bin/echo $(tr -dc [:alnum:] </dev/urandom | head -c $arg_size) >/dev/null
Con el - 100
ser más que suficiente para explicar la diferencia entre el tamaño del entorno en el shell y el echo
proceso. En cambio, recibí el error:
bash: /bin/echo: Argument list too long
Después de jugar un rato, descubrí que el máximo era un orden hexadecimal completo de menor magnitud:
/bin/echo \
$(tr -dc [:alnum:] </dev/urandom | head -c $(($(getconf ARG_MAX)/16-1))) \
>/dev/null
Cuando se elimina el menos uno, el error regresa. Aparentemente, el máximo para un solo argumento es en realidad ARG_MAX/16
y las -1
cuentas para el byte nulo colocado al final de la cadena en la matriz de argumentos.
Otro problema es que cuando se repite el argumento, el tamaño total de la matriz de argumentos puede estar más cerca ARG_MAX
, pero aún no del todo:
args=( $(tr -dc [:alnum:] </dev/urandom | head -c $(($(getconf ARG_MAX)/16-1))) )
for x in {1..14}; do
args+=( ${args[0]} )
done
/bin/echo "${args[@]}" "${args[0]:6534}" >/dev/null
Usar "${args[0]:6533}"
aquí hace que el último argumento 1 byte sea más largo y da el Argument list too long
error. Es improbable que esta diferencia se deba al tamaño del entorno dado:
$ cat /proc/$$/environ | wc -c
1045
Preguntas:
- ¿Es este comportamiento correcto o hay algún error en alguna parte?
- Si no, ¿se documenta este comportamiento en alguna parte? ¿Hay otro parámetro que defina el máximo para un solo argumento?
- ¿Se limita este comportamiento a Linux (o incluso a versiones particulares de este)?
- ¿Qué explica la discrepancia adicional de ~ 5 KB entre el tamaño máximo real de la matriz de argumentos más el tamaño aproximado del entorno y
ARG_MAX
?
Información adicional:
uname -a
Linux graeme-rock 3.13-1-amd64 #1 SMP Debian 3.13.5-1 (2014-03-04) x86_64 GNU/Linux
getconf ARG_MAX
depende de la corriente ulimit -s
. Configúrelo como ilimitado y obtenga un increíble 4611686018427387903 para ARG_MAX.