“参数列表太长”限制是否适用于shell内置函数?

时间:2017-11-22 20:28:07

标签: linux bash shell unix command-line-arguments

我浏览了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 ...

有人可以澄清一下吗?

2 个答案:

答案 0 :(得分:9)

在bash中,操作系统对命令行长度的强制限制导致错误argument list too long不适用于shell内置。

execve()系统调用返回错误代码E2BIG时会触发此错误。 execve()调用,因此无法发生错误。

因此,您提出的两个操作都是安全的: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)(在最近的内核中也可以通过其他方式)。几年前,这是我重新编译内核的强烈动机。