Bash 脚本:[ 测试 ] 中的参数太多
Bash script: too many arguments in [ test ]
我有下面的 bash 脚本:
#!/bin/bash
#
[ $# -eq 1 -a = "--help" -o $# -eq 0 ] && {
echo Help will come here
}
当我运行它时:
$ ./script
./script: line 3: [: too many arguments
$ ./script --help
Help will come here
如您所见,当我不传递参数 ($# -eq 0) 时,它失败并显示 "too many arguments"。
所以,我直接在终端测试了:
$ 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
那么,如果它在终端中完美运行,为什么它不能传递参数?
谢谢,
这样表达你的情况:
[ $# -eq 1 ] && [ "" = "--help" ] || [ $# -eq 0 ]
其实[
是一个命令,命令中的以下元素进行分词。如果参数为空(或包含空格且未加引号),您可以 运行 出乎意料。使用 -a
和 -o
已弃用。
请注意,如果您想在 echo
语句之前使用 &&
逻辑运算符(而不是 if
语句),您需要将上面的内容括在里面大括号,否则运算符优先级(加上惰性求值)可能会产生不正确的结果。
{ [ $# -eq 1 ] && [ "" = "--help" ] || [ $# -eq 0 ] ; } && { echo...
如果您不介意使用 Bash 特定的语法,您也可以这样写:
[[ $# -eq 1 && = "--help" || $# -eq 0 ]]
请注意,在这种情况下,不需要双引号 </code>,因为 <code>[[ ]]
构造是特殊的 shell 语法,而不是命令,里面的内容不是受分词影响。因为只有一个测试,所以您不需要在 && { echo...
.
之前将它括在大括号内
试试这个:-
[ $# -eq 1 ] || [ $1 = "--帮助"] || [ $# -eq 0 ]
如果提供 --help 或键入 1,它将自动显示。
我认为 $# 造成了问题,因为第一个和第二个条件都有 $#
当您在不带参数的情况下执行脚本时,您会收到错误消息,因为您的条件与空白字符匹配,请参见下文 -
$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 条件,如果没有值,则分配一个虚拟值。
你的整个表达式可以简化为:
function help () {
printf "%s\n" "help is on it's way."
}
[[ $# -eq 0 || "$*" = "--help" ]] && help ; echo "done." && exit 0 ;
这会检查参数的总和是否为零,或者参数是否等于“--help”。如果这两件事中的任何一个为真,那么它将继续执行 help
函数,否则回显 "done" 并退出。
我有下面的 bash 脚本:
#!/bin/bash
#
[ $# -eq 1 -a = "--help" -o $# -eq 0 ] && {
echo Help will come here
}
当我运行它时:
$ ./script
./script: line 3: [: too many arguments
$ ./script --help
Help will come here
如您所见,当我不传递参数 ($# -eq 0) 时,它失败并显示 "too many arguments"。 所以,我直接在终端测试了:
$ 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
那么,如果它在终端中完美运行,为什么它不能传递参数?
谢谢,
这样表达你的情况:
[ $# -eq 1 ] && [ "" = "--help" ] || [ $# -eq 0 ]
其实[
是一个命令,命令中的以下元素进行分词。如果参数为空(或包含空格且未加引号),您可以 运行 出乎意料。使用 -a
和 -o
已弃用。
请注意,如果您想在 echo
语句之前使用 &&
逻辑运算符(而不是 if
语句),您需要将上面的内容括在里面大括号,否则运算符优先级(加上惰性求值)可能会产生不正确的结果。
{ [ $# -eq 1 ] && [ "" = "--help" ] || [ $# -eq 0 ] ; } && { echo...
如果您不介意使用 Bash 特定的语法,您也可以这样写:
[[ $# -eq 1 && = "--help" || $# -eq 0 ]]
请注意,在这种情况下,不需要双引号 </code>,因为 <code>[[ ]]
构造是特殊的 shell 语法,而不是命令,里面的内容不是受分词影响。因为只有一个测试,所以您不需要在 && { echo...
.
试试这个:-
[ $# -eq 1 ] || [ $1 = "--帮助"] || [ $# -eq 0 ]
如果提供 --help 或键入 1,它将自动显示。
我认为 $# 造成了问题,因为第一个和第二个条件都有 $#
当您在不带参数的情况下执行脚本时,您会收到错误消息,因为您的条件与空白字符匹配,请参见下文 -
$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 条件,如果没有值,则分配一个虚拟值。
你的整个表达式可以简化为:
function help () {
printf "%s\n" "help is on it's way."
}
[[ $# -eq 0 || "$*" = "--help" ]] && help ; echo "done." && exit 0 ;
这会检查参数的总和是否为零,或者参数是否等于“--help”。如果这两件事中的任何一个为真,那么它将继续执行 help
函数,否则回显 "done" 并退出。