Ich hatte den Eindruck, dass die maximale Länge eines einzelnen Arguments hier nicht das Problem war, sondern vielmehr die Gesamtgröße des gesamten Argument-Arrays plus die Größe der Umgebung, die auf beschränkt ist ARG_MAX
. So dachte ich, dass so etwas gelingen würde:
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
Mit dem - 100
Sein mehr als genug, um den Unterschied zwischen der Größe der Umgebung in der Shell und dem echo
Prozess zu berücksichtigen. Stattdessen habe ich den Fehler bekommen:
bash: /bin/echo: Argument list too long
Nachdem ich eine Weile herumgespielt hatte, stellte ich fest, dass das Maximum eine ganze Hex-Größenordnung kleiner war:
/bin/echo \
$(tr -dc [:alnum:] </dev/urandom | head -c $(($(getconf ARG_MAX)/16-1))) \
>/dev/null
Wenn das Minuszeichen entfernt wird, wird der Fehler zurückgegeben. Scheinbar ist das Maximum für ein einzelnes Argument tatsächlich ARG_MAX/16
und die -1
Konten für das Nullbyte, das am Ende der Zeichenfolge im Argumentarray platziert wird.
Ein weiteres Problem ist, dass bei Wiederholung des Arguments die Gesamtgröße des Argument-Arrays näher sein kann ARG_MAX
, aber immer noch nicht ganz da ist:
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
Die Verwendung von "${args[0]:6533}"
here verlängert das letzte Argument um 1 Byte und gibt den Argument list too long
Fehler aus. Es ist unwahrscheinlich, dass dieser Unterschied auf die Größe der gegebenen Umgebung zurückzuführen ist:
$ cat /proc/$$/environ | wc -c
1045
Fragen:
- Ist das korrekt oder gibt es irgendwo einen Fehler?
- Wenn nicht, ist dieses Verhalten irgendwo dokumentiert? Gibt es einen anderen Parameter, der das Maximum für ein einzelnes Argument definiert?
- Ist dieses Verhalten auf Linux (oder sogar bestimmte Versionen davon) beschränkt?
- Was erklärt die zusätzliche Diskrepanz von ~ 5 KB zwischen der tatsächlichen Maximalgröße des Argument-Arrays plus der ungefähren Größe der Umgebung und
ARG_MAX
?
Zusätzliche Information:
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
hängt von der Stromstärke ab ulimit -s
. Setzen Sie es auf unbegrenzt und erhalten Sie eine erstaunliche 4611686018427387903 für ARG_MAX.