首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么在传递带引号的参数时会出现"/bin/sh:参数列表太长“?

为什么在传递带引号的参数时会出现"/bin/sh:参数列表太长“?
EN

Stack Overflow用户
提问于 2012-07-14 01:14:30
回答 4查看 40K关注 0票数 29

可以传递给sh -c ''的命令行可以有多长?(在bash和bourne shell中)

这一限制远低于操作系统的限制(在现代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

现在我明白了这里的重点是什么。这不是shell限制,而是系统限制,而是每个参数的长度,而不是整个arglist的长度。

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

谢谢你,CodeGnome,你的解释。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-07-14 01:52:27

TL;DR

单个参数必须短于MAX_ARG_STRLEN。

分析

根据this link的说法

和2.6.23之后的附加限制,一个参数不能长于MAX_ARG_STRLEN (131072)。如果生成像"sh -c 'generated with long arguments'“这样的长调用,这可能会变得相关。

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

特定于实施

参数限制是特定于实现的。然而,this Linux Journal article建议了几种方法来解决这些问题,包括增加系统限制。这可能不直接适用于OP,但在一般情况下仍然有用。

做一些其他的事情

行动的问题实际上并不是一个真正的问题。问题是强加一个不能解决现实世界问题的任意约束。

您可以通过使用循环轻松地解决此问题。例如,使用Bash 4:

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

工作得很好。它肯定会很慢,因为您在每次循环中都会产生一个进程,但它确实绕过了您正在经历的命令行限制。

描述你真正的问题

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

票数 26
EN

Stack Overflow用户

发布于 2012-07-14 02:48:56

我不明白那个错误信息。我的秘密?单引号:

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

如果我使用双引号,每个shell都会出现错误:

$ /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

当使用双引号时,参数列表将在当前shell中展开,事实证明,发出错误"-bash:...“的是Bash。而不管使用哪个shell来运行该命令。顺便说一下,在我的系统中,sh是破折号。

这一点甚至适用于其他“主机”shell:

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

病人:医生,我这样做的时候很痛。“

医生:不要那样做。

票数 4
EN

Stack Overflow用户

发布于 2012-07-14 01:46:19

#!/bin/sh作为第一行创建一个文件,然后将命令的其余部分放到后续行?:)

更重要的是,您还可以使用-s选项从STDIN读取命令,这样就可以生成很长的命令行并将其通过管道传输到/bin/sh -s

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11475221

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档