我的印象是,这里单个参数的最大长度不是问题,而是整个参数数组的总大小加上环境的大小(最大为)ARG_MAX
。因此,我认为类似以下内容的方法将会成功:
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
就足以解决shell中环境大小与echo
进程之间的差异。相反,我得到了错误:
bash: /bin/echo: Argument list too long
玩了一段时间后,我发现最大值比整数小了一个十六进制数量级:
/bin/echo \
$(tr -dc [:alnum:] </dev/urandom | head -c $(($(getconf ARG_MAX)/16-1))) \
>/dev/null
减一时,错误返回。似乎单个参数的最大值实际上是,ARG_MAX/16
并且将-1
空字节放在参数数组中字符串的末尾。
另一个问题是,当重复参数时,参数数组的总大小可能更接近ARG_MAX
,但仍然不够大:
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
使用"${args[0]:6533}"
此处会使最后一个参数增加1个字节并给出Argument list too long
错误。所给出的环境大小不可能解释这种差异:
$ cat /proc/$$/environ | wc -c
1045
问题:
- 这是正确的行为,还是某个地方有错误?
- 如果不是,是否在任何地方记录了此行为?是否有另一个参数定义单个参数的最大值?
- 这种行为是否仅限于Linux(甚至是特定版本)?
- 是什么导致参数数组的实际最大大小加上环境的近似大小与之间的〜5KB额外差异
ARG_MAX
?
附加信息:
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
取决于电流ulimit -s
。将其设置为无限制,并获得惊人的4611686018427387903 ARG_MAX。