我浏览了Stack Overflow上的许多posts以及关于argument list too long
主题的一些相关社区,我似乎没有清楚地知道长度限制是否适用于shell内置
假设我想通过标准输入将一个非常长的字符串传递给命令:
string="a very long list of words ..."
我可以说:
# not using double quotes around $string is deliberate
printf '%s\n' $string | cmd ...
或
cmd <<< $string
甚至可以将其传递给xargs
:
printf '%s\n' $string | xargs cmd ...
有人可以澄清一下吗?
答案 0 :(得分:9)
在bash中,操作系统对命令行长度的强制限制导致错误argument list too long
不适用于shell内置。
execve()
系统调用返回错误代码E2BIG
时会触发此错误。
因此,您提出的两个操作都是安全的:cmd <<< "$string"
将$string
写入临时文件,该文件不要求将其作为argv元素(或存储的环境变量)传递在同一个预留空间池中);并且printf '%s\n' "$cmd"
发生在shell内部,除非已修改shell的配置(与enable -n printf
一样),以使用外部printf
实现。
答案 1 :(得分:3)
我似乎不知道长度限制是否适用于shell builtins。
可能不是,但您应该查看特定版本bash
的源代码(因为它是免费软件)。但是,显然存在一些 - 更大的限制(特别是因为在malloc
内完成的某些bash
可能会失败),但随后您将收到另一个错误消息或行为。
AFAIK,参数列表太长错误由execve(2)给出E2BIG
失败,而bash的内置函数不fork
然后execve
(如命令调用)外部程序确实如此。
在实践中,E2BIG
可能会出现几十万个字节(确切的限制取决于内核和系统)但我想内置可以使用几十兆字节(在今天的桌面上)。但YMMV(因为你可以使用ulimit
让你的shell做一些setrlimit(2) ...)。我不建议通过shell内置函数处理千兆字节的数据。
BTW,xargs(1)可能会有所帮助,您甚至可以通过重新编译内核来提高限制(对于E2BIG
)(在最近的内核中也可以通过其他方式)。几年前,这是我重新编译内核的强烈动机。