Bash脚本:[test]中的参数太多

时间:2017-04-09 17:53:26

标签: linux bash testing quoting

我有以下bash脚本:

#!/bin/bash
#
[ $# -eq 1 -a $1 = "--help" -o $# -eq 0 ] && {
  echo Help will come here
}

当我运行它时:

$ ./script 
./script: line 3: [: too many arguments
$ ./script --help
Help will come here

正如你所看到的,当我没有传递参数($#-eq 0)时,它失败了“参数太多”。 所以,我直接在终端测试了它:

$ a=1;b=2;c=3
$ [ $a -eq 1 -a $b -eq 2 -o $c -eq 3 ] && echo ok
ok
$ [ $a -eq 0 -a $b -eq 2 -o $c -eq 3 ] && echo ok
ok
$ [ $a -eq 0 -a $b -eq 0 -o $c -eq 3 ] && echo ok
ok
$ [ $a -eq 0 -a $b -eq 0 -o $c -eq 0 ] && echo ok
$ [ $a -eq 0 -a $b -eq 2 -o $c -eq 0 ] && echo ok
$ [ $a -eq 1 -a $b -eq 2 -o $c -eq 0 ] && echo ok
ok

那么,如果它在终端中完美运行,为什么它不能传递参数呢?

谢谢,

4 个答案:

答案 0 :(得分:3)

表达你的情况:

[ $# -eq 1 ] && [ "$1" = "--help" ] || [ $# -eq 0 ]

实际上,[是一个命令,命令中的以下元素可以进行分词。如果参数为空(或包含空格且未加引号),则可能会遇到意外情况。不推荐使用-a-o

请注意,如果要在&&语句之前使用if逻辑运算符(而不是echo语句),则需要将上面的括号括起来,否则运算符优先级(加上延迟评估)可能会产生不正确的结果。

{ [ $# -eq 1 ] && [ "$1" = "--help" ] || [ $# -eq 0 ] ; } && { echo...

如果您不介意使用特定于Bash的语法,您还可以编写:

[[ $# -eq 1 && $1 = "--help" || $# -eq 0 ]]

请注意,在这种情况下,不需要双引号$1,因为[[ ]]构造是特殊的shell语法,而不是命令,并且内部的内容不受单词拆分的影响。因为只有一个测试,所以您不需要在&& { echo...之前将其括在大括号内。

答案 1 :(得分:1)

您的整个表达可以简化为:

function help () {
    printf "%s\n" "help is on it's way."
}

[[ $# -eq 0 || "$*" = "--help" ]] && help ; echo "done." && exit 0 ;

检查参数的总和是否为零,或者参数是否等于“--help”。如果这两个中的任何一个都为真,那么它将进入help函数,否则回显“完成”并退出。

答案 2 :(得分:0)

当您执行不带参数的脚本时,您收到错误,因为您的条件与空白字符匹配,请参阅下面的内容 -

$sh -x kk.sh 
+ '[' 0 -eq 1 -a = --help -o 0 -eq 0 ']'
kk.sh: line 3: [: too many arguments

正如您所看到的,没有值可以匹配。

当你在终端执行以下命令时 -

$[ $a -eq 1 -a $b -eq 2 -o $c -eq 3 ] && echo ok
-bash: [: too many arguments
$a=1;b=2;c=3
$[ $a -eq 1 -a $b -eq 2 -o $c -eq 3 ] && echo ok
ok ####it is printing this value bcoz you have set the variable to match, it doesn't matter condition is wrong or right but there is something to match.

要解决此问题,您可以在开头使用一个if条件,以便在没有值的情况下分配虚拟值。

答案 3 :(得分:-1)

试试这个: -

[$#-eq 1] || [$ 1 =" - 帮助" ] || [$#-eq 0]

这样,如果提供了--help或输入了1,它将自动显示。

我认为$#正在创造问题,因为第一和第二个条件都有$#