在 shell 中,正如本问答在扩展上下文中所解释的,根据系统,命令参数的最大长度最初受内核设置的约束。最大值在运行时使用getconf
命令显示(另请参见IEEE Std 1003.1, 2013 Edition):
# getconf ARG_MAX
2097152
vs. value found in limits.h on my setup:
#define ARG_MAX 131072 /* # bytes of args + environ for exec() */
Run Code Online (Sandbox Code Playgroud)
的确:
sysconf() 调用提供一个值,该值对应于程序编译或执行时的条件,具体取决于实现;对 getconf 的 system() 调用总是在程序执行时提供与条件相对应的值。
联机帮助页参考了 POSIX,从暗指POSIX 程序员手册的序言到描述本身:
应确定每个配置变量的值,就好像它是通过调用定义为可用的函数获得的,POSIX.1-2008 的本卷或 POSIX.1-2008 的系统接口卷(参见操作数部分)。该值应反映当前操作环境中的条件。
可以查询的基本变量出现在sysconf
函数规范表中,limits.h
头文件中有关于这些值的更多信息:
{ARG_MAX}
Maximum length of argument to the exec functions including environment data.
Minimum Acceptable Value: {_POSIX_ARG_MAX}
...(nb you cannot be POSIX compliant under a certain value...)
{_POSIX_ARG_MAX}
Maximum length of argument to the exec functions including environment data.
Value: 4 096
Run Code Online (Sandbox Code Playgroud)
该xargs --show-limits
命令确认了其中的一些内容:
Your environment variables take up 3134 bytes
POSIX upper limit on argument length (this system): 2091970
POSIX smallest allowable upper limit on argument length (all systems): 4096
Maximum length of command we could actually use: 2088836
Size of command buffer we are actually using: 131072
Run Code Online (Sandbox Code Playgroud)
sysconf
最初设计用于查找 PATH 变量的系统值,然后扩展到其他变量。现在,Open Group文档探讨了拥有这样一个框架的基本原理,其中应用程序可以在运行时轮询系统变量,以及有关基线的相关实际考虑...:
(...) 如果仅限于标题中最严格的值,则此类应用程序必须准备好接受由最小的微型计算机提供的最有限的环境。尽管这完全是可移植的,但人们一致认为它们应该能够利用大型系统提供的设施,而不受与源和对象分发相关的限制。
在讨论此功能期间,有人指出,应用程序几乎总是可以通过适当地测试各种函数本身来辨别运行时可能是什么值。并且,在任何情况下,它始终可以编写为充分处理来自各种函数的错误返回。最后,人们认为这给应用程序开发人员带来了不合理的复杂性和复杂性。
...以及这种设置的缺点,因为它与某些文件变量有关fpathconf
:
pathconf() 函数是在 sysconf() 函数之后提出的,当时意识到某些可配置值可能会因文件系统、目录或设备边界而异。
例如,{NAME_MAX} 在 System V 和基于 BSD 的文件系统之间频繁变化;System V 最多使用 14 个,BSD 255。在提供两种类型文件系统的实现中,应用程序将被迫将所有路径名组件限制为 14 个字节,因为这将是在此类系统中指定的值。
因此,目的是减轻开发人员对基线的一些负担,同时也承认文件系统的多样性,并且通常允许对平台的不同变体进行一些定制。硬件、Unix和相关标准(C 和 POSIX)的演变在这里发挥了作用。
问题:
getconf
没有一个“列表”选项,然后set
,printenv
或export
不显示这些变量。是否有列出它们值的命令?fpathconf
看起来是为了引入更多的灵活性,但仅适用于 PATH 和文件相关的系统变量?仅仅是因为当时 getconf 只是关于 PATH 吗?limits.h
和编译的做法针对特定需求?limits.h
与在运行时使用ulimit -s
命令之类的东西更改变量与让内核直接管理它之间有什么区别?特别是limits.h
由于内核更改,我在 Linux 上过时的变量的(低)值是否已被取代?bash
什么地方?没有标准方法来检索系统支持的配置变量列表。如果您针对给定的 POSIX 版本进行编程,则该版本的 POSIX 规范中的列表就是您的参考列表。在 Linux 上,getconf -a
列出所有可用变量。
fpathconf
不是特定于 PATH 的。它涉及与文件相关的变量,这些变量可能因文件而异。
在 Linux 上,取决于ARG_MAX
堆栈大小的基本原理是参数最终位于堆栈上,因此最好有足够的空间容纳它们以及必须容纳的其他所有内容。大多数其他实现(包括旧版本的 Linux)都有固定的大小。
大多数限制与资源可用性相关,不同的资源取决于限制。OPEN_MAX
例如,如果系统没有可用于文件相关数据的内存,则进程可能无法打开文件,即使打开的文件数少于文件数。
Linux 在这一点上默认是兼容 POSIX 的,所以我不知道你的意思。
如果您将ulimit -s
堆栈大小限制为小于ARG_MAX
,则系统将不再合规。POSIX 系统通常可以通过多种方式变得不合规,包括PATH=/nowhere
(使所有标准实用程序不可用)或rm -rf /
。
ARG_MAX
in的值limits.h
提供了应用程序可以依赖的最小值。execve
即使参数超过该大小,符合 POSIX 的系统也允许 let成功。相关的保证ARG_MAX
是,如果参数适合该大小,则execve
不会因 原因而失败E2BIG
。