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

Posted

技术标签:

【中文标题】“参数列表太长”限制是不是适用于 shell 内置函数?【英文标题】:Does "argument list too long" restriction apply to shell builtins?“参数列表太长”限制是否适用于 shell 内置函数? 【发布时间】:2018-05-06 16:54:06 【问题描述】:

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

有人可以澄清一下吗?

【问题讨论】:

相关文档:ARG_MAX, maximum length of arguments for a new process 相关:Bash command line and input limit. 【参考方案1】:

我似乎不知道长度限制是否适用于 shell 内置函数。

可能不会,但您应该检查您的特定版本的bash 的源代码(因为它是免费软件)。但是,显然存在一些 - 希望更大 - 限制(特别是因为在 bash 内完成的一些 malloc 可能会失败),但随后您会收到另一个错误消息或行为。

AFAIK,参数列表太长的错误是由execve(2) 失败并出现E2BIG 给出的,bash 的内置函数不是fork 然后是execve(就像调用外部程序的命令一样)。

在实践中,E2BIG 可能会出现几十万字节(确切的限制取决于内核和系统),但我猜内置函数可以用于几十兆字节(在今天的桌面上)。但是 YMMV(因为你可以使用 ulimit 让你的 shell 做一些 setrlimit(2)...)。我不建议通过 shell 内置函数处理千兆字节的数据。

顺便说一句,xargs(1) 可能会有所帮助,您甚至可以通过重新编译您的内核(以及通过一些其他方式,在最近的内核中)来提高限制(对于 E2BIG)。几年前,这是我重新编译内核的强烈动力。

【讨论】:

这里的一切都是真实的——但如果 malloc 失败 (f/e),那将是 argument list too long 以外的错误。 当然。我写了什么让你这么想吗? 我从上下文中得到它,因为这个问题明确询问“参数列表太长”。【参考方案2】:

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

execve() 系统调用返回错误代码E2BIG 时会触发此错误。调用内置函数时不涉及 execve() 调用,因此不会发生错误。

因此,您提出的两个操作都是安全的:cmd &lt;&lt;&lt; "$string"$string 写入临时文件,这不需要将其作为 argv 元素(或存储在同一个池中的环境变量)传递预留空间); printf '%s\n' "$cmd" 发生在 shell 内部,除非 shell 的配置已被修改,如 enable -n printf,以使用外部 printf 实现。

【讨论】:

以上是关于“参数列表太长”限制是不是适用于 shell 内置函数?的主要内容,如果未能解决你的问题,请参考以下文章

AngularJS - JQuery UI 是不是适用于内置的 JQLite [重复]

参数列表太长 - lint-staged -> tslint

软删除是不是适用于流明框架?流明的限制?

HttpWebRequest 对每个主机 2 个连接的限制是不是适用于 HttpClient?

为啥使用通配符将参数数量减半会因“参数列表太长”而失败? [复制]

参数列表太长:递归头扩展失败