为什么我会收到“/ bin / sh的:参数列表太长”引用传递参数时?(Why do I get “

2019-06-17 10:53发布

能够维持多久可以传递到命令行sh -c '' ? (在bash和Bourne shell)中

该限制是比从OS(在现代的Linux的情况下)低得多。

例如:

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

我怎么能解决这个问题?

更新

我想指出, getconf不能帮助这里(因为这不是一个系统限制):

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

更新#2

现在我明白了什么是点这里。 这不是一个限制壳,这是一个系统限制,但对于每个参数的长度,而不是针对整个arglist中。

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

谢谢你,CodeGnome,对于解释。

Answer 1:

TL; DR

一个单一的参数必须比MAX_ARG_STRLEN短。

分析

根据此链接 :

而作为附加的限制,因为2.6.23,一种说法不能长于MAX_ARG_STRLEN(131072)。 如果你生成一个长调用,如“SH -c‘长参数生成’。”这可能成为相关。

这也正是“问题”由OP确定。 虽然允许的可能相当大参数的数量(见getconf ARG_MAX ),当你通过一个引用命令/ bin / sh的外壳解释引用命令作为一个字符串。 在OP的例子,它是超过MAX_ARG_STRLEN限制,不被扩展的参数列表的长度,这种单一的字符串。

具体实施

参数限制是实现特定的。 然而, 这篇Linux Journal中推荐了几种方法来解决它们,其中包括增加了系统的限制。 这可能不是直接适用于OP,但在一般情况下仍然有用。

做别的事情

该任择议定书的问题实际上不是一个真正的问题。 现在的问题是气势不解决实际问题的任意约束。

您可以通过使用循环解决此很轻松了。 例如,对于击4:

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

工作得很好。 这肯定将是缓慢的,因为你产卵一个过程每次通过循环,但它肯定在你身边所遇到的命令行的限制得到。

描述你真正的问题

如果循环无法解决您的问题,请更新的问题来描述你实际上尝试使用很长的参数列表来解决这个问题。 探索独断专行长度限制是一个学术活动,并为堆栈溢出不是话题。



Answer 2:

我没有得到错误信息。 我的秘密? 单引号:

/bin/sh -c '/bin/true $(seq 1 100000)'

如果我使用双引号,我与每一个外壳的错误:

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

“-bash:......”的事实,Bash是一个发出错误证明的参数列表获取当前外壳扩展,当使用双引号无论是外壳被用来运行命令。 在我的系统sh是短跑,顺便说一句。

即使对于其他的“主机”炮弹成立:

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

病人:医生,就当我这样做伤害“。
医生:不要做。



Answer 3:

减少10万,直到不再出现错误

/bin/sh -c "/bin/true $(seq 1 99999)"
/bin/sh -c "/bin/true $(seq 1 99998)"

等等



Answer 4:

请与文件#!/bin/sh作为第一行,那么你的命令在后面的行认沽休息吗? :)

更为严重的是,你还可以从标准输入使用读取命令-s选项,这样你就可以生成你的长期命令行,管它/bin/sh -s



Answer 5:

在我的操作系统是由二分法获得的最大长度

/bin/sh -c "/bin/true $(perl -e 'print"a"x131061')"

所以它给131071

但没有理由让一个线长; 如果是由于大量的参数,“$ @”可以用来代替; 例如

/bin/sh -c 'command "$@"' -- arg1 arg2 .. argn


文章来源: Why do I get “/bin/sh: Argument list too long” when passing quoted arguments?