Fiquei com a impressão de que o tamanho máximo de um único argumento não era o problema aqui, tanto quanto o tamanho total da matriz geral de argumentos mais o tamanho do ambiente, ao qual está limitado ARG_MAX
. Assim, pensei que algo como o seguinte seria bem-sucedido:
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
- 100
Sendo o suficiente para explicar a diferença entre o tamanho do ambiente no shell e o echo
processo. Em vez disso, recebi o erro:
bash: /bin/echo: Argument list too long
Depois de brincar um pouco, descobri que o máximo era uma ordem hexadecimal completa de magnitude menor:
/bin/echo \
$(tr -dc [:alnum:] </dev/urandom | head -c $(($(getconf ARG_MAX)/16-1))) \
>/dev/null
Quando o menos um é removido, o erro retorna. Aparentemente, o máximo para um único argumento é realmente ARG_MAX/16
e as -1
contas para o byte nulo são colocadas no final da cadeia de caracteres na matriz de argumentos.
Outra questão é que, quando o argumento é repetido, o tamanho total da matriz de argumentos pode estar mais próximo ARG_MAX
, mas ainda não está lá:
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
O uso "${args[0]:6533}"
aqui torna o último argumento 1 byte mais longo e fornece o Argument list too long
erro. É improvável que essa diferença seja explicada pelo tamanho do ambiente fornecido:
$ cat /proc/$$/environ | wc -c
1045
Questões:
- Esse comportamento é correto ou existe algum bug em algum lugar?
- Caso contrário, esse comportamento está documentado em algum lugar? Existe outro parâmetro que define o máximo para um único argumento?
- Esse comportamento é limitado ao Linux (ou mesmo a versões específicas)?
- O que explica a discrepância adicional de ~ 5 KB entre o tamanho máximo real da matriz de argumentos mais o tamanho aproximado do ambiente e
ARG_MAX
?
Informação 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 da corrente ulimit -s
. Defina-o como ilimitado e obtenha um incrível 4611686018427387903 para ARG_MAX.