I was under the impression that the maximum length of a single argument was not the problem here so much as the total size of the overall argument array plus the size of the environment, which is limited to ARG_MAX
. Thus I thought that something like the following would succeed:
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
With the - 100
being more than enough to account for the difference between the size of the environment in the shell and the echo
process. Instead I got the error:
bash: /bin/echo: Argument list too long
After playing around for a while, I found that the maximum was a full hex order of magnitude smaller:
/bin/echo \
$(tr -dc [:alnum:] </dev/urandom | head -c $(($(getconf ARG_MAX)/16-1))) \
>/dev/null
When the minus one is removed, the error returns. Seemingly the maximum for a single argument is actually ARG_MAX/16
and the -1
accounts for the null byte placed at the end of the string in the argument array.
Another issue is that when the argument is repeated, the total size of the argument array can be closer to ARG_MAX
, but still not quite there:
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
Using "${args[0]:6533}"
here makes the last argument 1 byte longer and gives the Argument list too long
error. This difference is unlikely to be accounted for by the size of the environment given:
$ cat /proc/$$/environ | wc -c
1045
Questions:
- Is this correct behaviour, or is there a bug somewhere?
- If not, is this behaviour documented anywhere? Is there another parameter which defines the maximum for a single argument?
- Is this behaviour limited to Linux (or even particular versions of such)?
- What accounts for the additional ~5KB discrepancy between the actual maximum size of the argument array plus the approximate size of the environment and
ARG_MAX
?
Additional info:
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
depends on the currentulimit -s
. Set it to unlimited, and get an amazing 4611686018427387903 for ARG_MAX.