我浏览了很多关于StackOverflow的post以及一些相关的社区,关于argument list too long
话题,我似乎没有清楚地指出长度限制是否适用于shell buildins。
比方说,我有一个很长的string,我想通过标准input传递给一个命令:
string="a very log list ..."
我能说……么:
# not using double quotes around $string is deliberate printf '%s\n' $string | cmd ...
要么
cmd <<< $string
甚至xargs
到xargs
:
printf '%s\n' $string | xargs cmd ...
有人可以澄清这一点?
在bash中,操作系统对导致错误argument list too long
命令行长度的限制不适用于shell内建argument list too long
。
当execve()
系统调用返回错误码E2BIG
时,会触发此错误。 调用内置函数时不涉及execve()
调用,所以错误不能发生。
因此,你提出的两个操作都是安全的: cmd <<< "$string"
将$string
写入一个临时文件,它不要求它作为一个argv元素传递(或者是一个环境变量,预留空间池); 和printf '%s\n' "$cmd"
发生在shell的内部,除非已经修改了shell的配置,像enable -n printf
,使用一个外部的printf
实现。
我似乎并不认为如果长度限制适用于壳建筑或不。
可能不是,但你应该检查你的特定版本的bash
的源代码(因为它是自由软件)。 然而,显然有一些更大的限制(特别是因为在bash
完成的一些malloc
可能会失败),但是会得到另一个错误信息或行为。
AFAIK,参数列表太长错误是由execve(2)与E2BIG
失败给出的,并且bash的内建函数不fork
然后execve
(如调用外部程序那样的命令)。
在实践中, E2BIG
可能会出现几十万字节(确切的限制取决于内核和系统),但是我猜这些内建函数可能在几十兆字节(在今天的桌面上)上使用。 但YMMV(因为你可以使用ulimit
让你的shell做一些setrlimit(2) …)。 我不建议通过shell内建处理千兆字节的数据。
顺便说一句, xargs(1)可以是有帮助的,你甚至可以通过重新编译你的内核(也可以通过其他方式,在最近的内核中)来提高E2BIG
的限制。 几年前,这是我重新编译内核的强烈动机。