mal*_*lat 2 shell bash limit posix
因此,根据POSIX 规范,我们有以下定义*
:
扩展到位置参数,从 1 开始,最初为设置的每个位置参数生成一个字段。当扩展发生在将执行字段拆分的上下文中时,任何空字段都可能会被丢弃,并且每个非空字段应进一步拆分,如字段拆分中所述。当扩展发生在不进行字段拆分的上下文中时,如果 IFS 至少包含一个字符,则初始字段应连接形成单个字段,其中每个参数的值由 IFS 变量的第一个字符分隔,或如果 IFS 未设置,则由 a 分隔,如果 IFS 设置为空字符串,则不分隔。
对于绝大多数人来说,我们都知道著名的ARG_MAX
限制:
$ getconf ARG_MAX
2621440
Run Code Online (Sandbox Code Playgroud)
这可能导致:
$ cat * | sort -u > /tmp/bla.txt
-bash: /bin/cat: Argument list too long
Run Code Online (Sandbox Code Playgroud)
值得庆幸的是,背后的好人bash
([包括所有类似 POSIX 的其他人])为我们提供printf
了内置功能,因此我们可以简单地:
printf '%s\0' * | sort -u --files0-from=- > /tmp/bla.txt
Run Code Online (Sandbox Code Playgroud)
一切对用户都是透明的。
有人可以让我知道为什么ARG_MAX
使用built-in
命令绕过限制是如此微不足道,以及为什么提供一个符合标准的 POSIX shell 解释器来处理*
一个独立的可执行文件的特殊参数是如此困难:
$ cat *
Run Code Online (Sandbox Code Playgroud)
那会破坏什么吗?我不是要求bash
人们提供cat
内置的,我只对操作顺序感兴趣,以及为什么*
根据命令是内置的还是独立的可执行文件以不同的行为展开。
Kusalananda的回答解释了为什么ARG_MAX
shell 内置函数不是问题。
至于以cat *
不受 影响的方式实现ARG_MAX
,这样做是微不足道的:cat
实现所需要做的就是使用它glob(3)
来实现自己的通配符,然后您可以使用cat \*
or运行它,cat '*'
以便外壳不执行其自己的通配符。您会在 Linux 或 Unix 风格的系统上找到一些命令,它们至少在某些情况下可以处理自己的通配符;find
, tar
,zip
等等。许多具有本机 DOS 版本的命令至少会包含处理通配符的代码,因为那里的 shell 本身不通配外部命令的参数。
鉴于对 POSIX shell 的期望,该功能将相当令人惊讶且难以发现!在早期的 Unix 版本中,通配符是使用单独的程序/etc/glob
.
归档时间: |
|
查看次数: |
4034 次 |
最近记录: |