Bash命令行和输入限制

Der*_*den 81 unix bash shell command-line-arguments

在bash(或其他shell)中是否存在某种字符限制,可以输入多长时间?如果是这样,那个字符限制是什么?

即是否可以在bash中编写一个命令行执行时间过长的命令?如果没有要求的限制,是否有建议的限制?

Jen*_*ens 112

命令行长度的限制不是由shell强加的,而是由操作系统强加的.此限制通常在100千字节的范围内.POSIX表示此限制ARG_MAX,在POSIX符合系统上,您可以使用它进行查询

$ getconf ARG_MAX    # Get argument limit in bytes
Run Code Online (Sandbox Code Playgroud)

例如在Cygwin上这是32000,在不同的BSD和Linux系统上,我使用它是从131072到2621440.

如果您需要处理超过此限制的文件列表,您可能需要查看该xargs实用程序,该实用程序使用不超过的参数子集重复调用程序ARG_MAX.

要回答您的具体问题,是的,可以尝试运行一个参数列表太长的命令.shell将出错,并且"参数列表太长".

需要注意的是输入一个程序(如读取标准输入或任何其他文件描述符)是受限(仅受可用程序资源).因此,如果shell脚本将字符串读入变量,则不受限制ARG_MAX.

  • 小警告.环境变量也很重要.[sysconf manpage](http://man7.org/linux/man-pages/man3/sysconf.3.html)>很难使用ARG_MAX,因为没有为exec指定多少>参数空间(3) )由用户的>环境变量消耗. (3认同)
  • @ user188737我觉得这是[BUGS]中的一个相当大的警告(http://man7.org/linux/man-pages/man3/sysconf.3.html#BUGS).例如,macOS 10.12.6上的`xargs`限制它尝试将一个`exec()`放到`ARG_MAX - 4096`中.所以使用`xargs`的脚本可能会起作用,直到有一天有人在环境中放入太多东西.现在进入这个(用它来处理:`xargs -s ???`). (3认同)
  • 以下是对记录的澄清:对于一个8兆字节的m4a文件,我做了:`blah ="$(cat/home/schwager/Music/Recordings/20090420\131623.m4a)"; 猫<<< $ blah>/dev/null`.注意没有错误. (2认同)
  • @Jens您的答案讨论了`fork()/exec()`限制,而不是关于shell可以在输入行上处理多少(交互式或非交互式)。– 所以这并没有回答问题。(我确实看到 shell 的一些命令调用其他程序,因此参数被传递到那里,但这是一个不同的故事。) (2认同)

Mik*_*e S 41

好的,Denizens.所以我已经接受命令行长度限制作为福音很长一段时间了.那么,如何处理一个人的假设呢?自然地检查它们.

我有一台Fedora 22机器(意思是:Linux使用bash4).我创建了一个目录,其中包含500,000个inode(文件),每个长度为18个字符.命令行长度为9,500,000个字符.创建如此:

seq 1 500000 | while read digit; do
    touch $(printf "abigfilename%06d\n" $digit);
done
Run Code Online (Sandbox Code Playgroud)

我们注意到:

$ getconf ARG_MAX
2097152
Run Code Online (Sandbox Code Playgroud)

但请注意我可以这样做:

$ echo * > /dev/null
Run Code Online (Sandbox Code Playgroud)

但这失败了:

$ /bin/echo * > /dev/null
bash: /bin/echo: Argument list too long
Run Code Online (Sandbox Code Playgroud)

我可以运行for循环:

$ for f in *; do :; done
Run Code Online (Sandbox Code Playgroud)

这是另一个内置的shell.

仔细阅读状态文档,ARG_MAX执行函数的最大参数长度.这意味着:没有通话exec,没有ARG_MAX限制.所以它可以解释为什么shell内置不受限制ARG_MAX.

事实上,ls如果我的参数列表长度为109948个文件,或者大约2,089,000个字符(给予或接受),我可以使用我的目录.但是,一旦我添加了一个18个字符的文件名文件,那么我会得到一个参数列表太长的错误.所以ARG_MAX正如所宣传的那样工作:exec ARG_MAX在参数列表中失败的是多个字符 - 包括应该注意的环境数据.

  • 是的,我认为很难记住 - 特别是对于更新的命令行afficianados-调用bash内置与fork/exec命令的情况在非显而易见的方面是不同的.我想说清楚.我总是在求职面试中遇到的一个问题(作为一个Linux Sysadmin)是,"所以我在一个目录中得到了一堆文件.我如何循环遍历所有这些......"提问者总是朝着这条线走去长度限制并想要一个find/while或xargs解决方案.在将来我会说,"啊,地狱 - 只需使用for循环.它可以处理它!" :-) (6认同)
  • @LesterCheung`for f in*; 回声$ f; 完成`将不会叉(所有内置).所以我不知道find-xargs组合会更快; 它尚未经过测试.实际上,我不知道OP的问题集是什么.也许`find/path/to/directory`对他没用,因为它会返回文件的路径名.也许他喜欢`for f in*`循环的简单性.无论如何,谈话是关于线路输入限制 - 而不是效率.所以让我们继续讨论与命令行长度有关的话题. (4认同)