可以传递给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,你的解释。
发布于 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的主题。
发布于 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
病人:医生,我这样做的时候很痛。“
医生:不要那样做。
发布于 2012-07-14 01:46:19
以#!/bin/sh
作为第一行创建一个文件,然后将命令的其余部分放到后续行?:)
更重要的是,您还可以使用-s
选项从STDIN读取命令,这样就可以生成很长的命令行并将其通过管道传输到/bin/sh -s
https://stackoverflow.com/questions/11475221
复制相似问题