ARG_MAX 是新进程的最大参数长度
如果您尝试调用具有太多参数的程序,即很可能与模式匹配有关,您将看到此错误消息:
$ command *
只有exec() 系统调用及其直接变体会产生此错误。它们返回相应的错误条件 E2BIG()。
shell 不应该受到责备,它只是将这个错误传递给您。
事实上,shell 扩展不是问题,因为这里还不需要 exec()。
扩展只受虚拟内存系统资源的限制。
因此,以下命令可以顺利运行,因为它们不会将太多参数传递给新进程,而是仅使用 shell 内置(echo)或使用控制结构(for 循环)迭代参数:
/dir-with-many-files$ echo * | wc -c
/dir-with-many-files$ for i in * ; do grep ARG_MAX "$i"; done
学习上限有不同的方法
命令: getconf ARG_MAX
系统调用: sysconf(_SC_ARG_MAX)
系统标头: ARG_MAX 在例如
与标题相反,sysconf 和 getconf 告诉实际有效的限制。
这与允许在运行时通过重新配置更改它的系统相关,
通过重新编译(例如 Linux)或应用补丁(HP-UX 10)。
sysconf() 的用法示例:
#include <stdio.h>
#include <unistd.h>
int main() {
return printf("ARG_MAX: %ld\n", sysconf(_SC_ARG_MAX));
}
如果您安装了 cpp,则可以方便地查找标题中的限制:
cpp <<EOF
#include <limits.h>
#include <param.h>
#include <params.h>
#include <sys/limits.h>
#include <sys/param.h>
#include <sys/params.h>
arg_max: ARG_MAX
ncargs: NCARGS
EOF
查看ARG_MAX/NCARGS 时,必须同时考虑argv[] 和envp[](参数和环境)的空间消耗。
因此,您必须至少将 ARG_MAX 减少 env|wc -c 和 env|wc -l * 4 的结果,以便更好地估计当前可用空间。
POSIX 建议额外减去 2048,以便进程可以节省地修改其环境。使用 getconf 命令快速估算:
expr `getconf ARG_MAX` - `env|wc -c` - `env|wc -l` \* 4 - 2048
获取当前可用空间的最可靠方法是测试 exec() 是否成功,并增加参数长度,直到失败。
这可能很昂贵,但至少你只需要检查一次,envp[]的长度是自动考虑的,结果是可靠的。
或者,可以使用 GNU autoconf check“检查命令行参数的最大长度...”。它的工作原理非常相似。
但是,出于意图和简单的原因,它导致的值要低得多(可能仅为实际值的四分之一):
在 n 增加的循环中,检查尝试使用参数长度为 2n 的 exec()(但不会检查 n 是否大于 16,即 512kB)。
如果 ARG_MAX 是 2 的幂,则最大值为 ARG_MAX/2。
最后,找到的值除以 2(为了安全),原因是“C++ 编译器可以添加大量附加参数”。
实际值
在 Linux 2.6.23 上,它是堆栈大小的 1/4。 Kernel code供参考。