Meaning of “[: too many arguments” error from if [] (square brackets)
我找不到任何一个简单直接的资源来解释下面bash shell错误的含义并修复它,所以我在研究之后发布了我发现的内容。
错误:
1 | -bash: [: too many arguments |
谷歌友好版:
上下文:单个方括号中的if条件,带有简单的比较运算符,如equals、greater than等,例如:
1 2 3 4 | VARIABLE=$(/some/command); if [ $VARIABLE == 0 ]; then # some action fi |
如果您的
这样一个变量就可以分成多个参数:
1 2 3 4 5 6 7 | VARIABLE=$(/some/command); # returns"hello world" if [ $VARIABLE == 0 ]; then # fails as if you wrote: # if [ hello world == 0 ] fi |
同样的情况也适用于任何函数调用,该函数调用会生成包含空格或其他特殊字符的字符串。
易修复将变量输出用双引号括起来,强制它保持为一个字符串(因此是一个参数)。例如,
1 2 3 4 | VARIABLE=$(/some/command); if ["$VARIABLE" == 0 ]; then # some action fi |
就这么简单。但是如果你也不能保证你的变量不是空字符串,或者一个只包含空白的字符串,那就跳到下面的"也要小心…"。
或者,另一种方法是使用双方括号(这是
但是,这只存在于bash(显然是korn和zsh)中,因此可能与
如下所示:
1 2 3 4 | VARIABLE=$(/some/command); if [[ $VARIABLE == 0 ]]; then # some action fi |
同时也要注意
如果您看到"参数太多"错误,那么很可能是从输出不可预测的函数中得到了一个字符串。如果还可以得到一个空字符串(或所有空白字符串),即使使用上面的"快速修复",这也将被视为零参数,并且使用
如果您习惯了其他语言,那么它就是相同的"gotcha"——您不希望在对变量进行评估之前将变量的内容有效地打印到代码中。
这里有一个例子可以防止
1 2 3 4 | VARIABLE=$(/some/command); if ["${VARIABLE:-0}" == 0 ]; then # some action fi |
(此处,如果$variable为0或为空,则会发生此操作。当然,如果需要不同的行为,您应该将0(默认值)更改为不同的默认值)
最后一点:由于
刚刚碰到这篇文章,得到了相同的错误,试图测试两个变量是否都是空的(或非空的)。结果是一个复合比较-7.3。其他比较运算符-高级bash脚本指南;我认为我应该注意以下几点:
- 我首先使用了
-e ->thinking it means"empty";但这意味着"file exists"-use-z for testing empty variable(string) - 需要引用字符串变量
- 对于复合逻辑和比较,可以是:
- 使用两个
test 和&& 它们:[ ... ] && [ ... ] 。 - 或者在单个
test 中使用-a 运算符:[ ... -a ... ] 。
- 使用两个
下面是一个工作命令(搜索目录中的所有txt文件,并转储
1 2 3 4 5 6 | find /usr/share/doc -name '*.txt' | while read file; do \ a1=$(grep -H"description" $file); \ a2=$(grep -H"changes" $file); \ [ ! -z"$a1" -a ! -z"$a2" ] && echo -e"$a1 $a2" ; \ done |
编辑2013年8月12日:相关问题注释:
注意,当用经典的
1 2 3 4 5 6 7 8 | $ if ["1"=="" ] ; then echo A; else echo B; fi A $ if ["1"="" ] ; then echo A; else echo B; fi A $ if ["1"="" ] && ["1"="1" ] ; then echo A; else echo B; fi A $ if ["1"=="" ] && ["1"=="1" ] ; then echo A; else echo B; fi A |
…但是增加空间-看起来都不错:
1 2 3 4 5 6 7 8 | $ if ["1" ="" ] ; then echo A; else echo B; fi B $ if ["1" =="" ] ; then echo A; else echo B; fi B $ if ["1" ="" -a"1" ="1" ] ; then echo A; else echo B; fi B $ if ["1" =="" -a"1" =="1" ] ; then echo A; else echo B; fi B |
有时,如果你不小心碰了键盘,就去掉了一个空格。
1 2 3 | if ["$myvar" ="something"]; then do something fi |
将触发此错误消息。注意"]"前的空格是必需的。
我的剧本也有同样的问题。但当我做了一些修改的时候,它对我有用。我是这样做的:
1 2 3 4 5 6 | export k=$(date"+%k"); if [ $k -ge 16 ] then exit 0; else echo"good job for nothing"; fi; |
这样我就解决了我的问题。希望这对你也有帮助。