为什么我会得到“/bin/sh:参数列表太长"?传递引用的参数时? [英] Why do I get "/bin/sh: Argument list too long" when passing quoted arguments?

查看:50
本文介绍了为什么我会得到“/bin/sh:参数列表太长"?传递引用的参数时?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一个命令行能传多长时间sh -c ''?(在 bash 和 bourne shell 中)

How long can be a command line that can be passed to sh -c ''? (in bash and in bourne shell)

限制远低于操作系统的限制(在现代 Linux 的情况下).

The limit is much lower than that from the OS (in case of modern Linux).

例如:

$ /bin/true $(seq 1 100000)
$ /bin/sh -c "/bin/true $(seq 1 100000)"
bash: /bin/sh: Argument list too long

我该如何规避这个问题?

And how could I circumvent this problem?

更新

我想说明 getconf 在这里帮不上忙(因为这不是系统限制):

I want to note that getconf can't help here (because that is not a system limit):

$ seq 1 100000 | wc -c
588895
$ getconf ARG_MAX
2097152

更新 #2

现在我明白了这里的意义所在.这不是 shell 限制,而是系统限制,而是针对每个参数的长度,而不是针对整个 arglist.

Now I've understood what is the point here. That is not a shell limit, that is a system limit but for the length of each argument, not for the entire arglist.

$ /bin/true $(seq 1 100000)
$ /bin/true "$(seq 1 100000)"
bash: /bin/true: Argument list too long

感谢 CodeGnome 的解释.

Thank you, CodeGnome, for the explanation.

推荐答案

TL;DR

单个参数必须短于 MAX_ARG_STRLEN.

TL;DR

A single argument must be shorter than MAX_ARG_STRLEN.

根据这个链接:

并且作为自 2.6.23 以来的附加限制,一个参数不得长于 MAX_ARG_STRLEN (131072).如果您生成像sh -c 'generated with long arguments'"这样的长调用,这可能会变得相关.

And as additional limit since 2.6.23, one argument must not be longer than MAX_ARG_STRLEN (131072). This might become relevant if you generate a long call like "sh -c 'generated with long arguments'".

这正是 OP 确定的问题".虽然允许的参数数量可能非常大(请参阅 getconf ARG_MAX),但当您将带引号的命令传递给 /bin/sh 时,shell 会将带引号的命令解释为单个细绳.在 OP 的示例中,正是这个单个字符串超出了 MAX_ARG_STRLEN 限制,而不是扩展参数列表的长度.

This is exactly the "problem" identified by the OP. While the number of arguments allowed may be quite large (see getconf ARG_MAX), when you pass a quoted command to /bin/sh the shell interprets the quoted command as a single string. In the OP's example, it is this single string that exceeds the MAX_ARG_STRLEN limit, not the length of the expanded argument list.

参数限制是特定于实现的.但是,这篇 Linux Journal 文章提出了几种解决方法,包括增加系统限制.这可能并不直接适用于 OP,但它在一般情况下仍然有用.

Argument limits are implementation specific. However, this Linux Journal article suggests several ways to work around them, including increasing system limits. This may not be directly applicable to the OP, but it nonetheless useful in the general case.

OP 的问题实际上并不是真正的问题.问题是强加一个不能解决现实问题的任意约束.

The OP's issue isn't actually a real problem. The question is imposing an arbitrary constraint that doesn't solve a real-world problem.

您可以使用循环轻松解决这个问题.例如,使用 Bash 4:

You can work around this easily enough by using loops. For example, with Bash 4:

for i in {1..100000}; do /bin/sh -c "/bin/true $i"; done

工作得很好.它肯定会很慢,因为您在每次通过循环时都会生成一个进程,但它肯定会绕过您遇到的命令行限制.

works just fine. It will certainly be slow, since you're spawning a process on each pass through the loop, but it certainly gets around the command-line limit you're experiencing.

如果循环不能解决您的问题,请更新问题以描述您实际尝试使用非常长的参数列表解决的问题.探索任意行长限制是一项学术活动,而不是 Stack Overflow 的主题.

If a loop doesn't resolve your issue, please update the question to describe the problem you're actually trying to solve using really long argument lists. Exploring arbitrary line-length limits is an academic exercise, and not on-topic for Stack Overflow.

这篇关于为什么我会得到“/bin/sh:参数列表太长"?传递引用的参数时?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆