问题描述
我正在运行一些传递字符串参数的脚本,如果else语句如下所示我想做:
if [ $1 != '' ] && [ $2 != '' ]
then
do something.....
但它显示了Error too many argument
。为什么?
最佳解决办法
尝试使用-z测试:
if [ -z "$1" ] && [ -z "$2" ]
来自man bash
:
-z string
True if the length of string is zero.
次佳解决办法
由于这是标记为bash
,我建议使用扩展测试构造([[...]]
),并忘记引号:
if [[ -z $1 && -z $2 ]]; then
...
除非您要使用sh
/POSIX兼容性,否则没有理由不使用[[ ]]
。
第三种解决办法
以下也有效,
if [ "$1" == "" && "$2" == ""]; then
echo NULL
fi
第四种办法
对于旧版本的答案,请参阅此答案的第二部分。如果您想了解详细信息,请继续阅读
问题的原因
在问题本身中,据报道OP看到too many arguments error
,当在bash
中测试时似乎不是这样的:
$ [ $1 != '' ] && [ $2 != '' ]
bash: [: !=: unary operator expected
使用/bin/sh
实际上符合Ubuntu上的/bin/dash
,错误报告如下:
$ sh
$ [ $1 != '' ] && [ $2 != '' ]
sh: 1: [: !=: unexpected operator
而独立的/bin/test
也是:
$ /usr/bin/test $1 != ''
/usr/bin/test: missing argument after ‘’
旁注:如果你想知道什么是/usr/bin/test
以及我为什么使用bash
和sh
,那么你应该知道[
是test
命令的别名,它也作为独立的可执行文件或更常见的存在 – 作为shell 内置这是每个shell的内容将首先使用。至于if
语句,它们对命令的退出状态进行操作,因此[
和test
是命令,其他所有命令都是该命令的参数 – 那些命令行参数的不正确顺序会导致错误。
回到主题:目前还不清楚OP如何得到无关的错误。但是,在所有3个案例中问题都是相同的 – 未设置的变量将被视为空,因此shell看到这些未加引号的变量是
[ != '' ]
这打破了test
理解的语法。还记得我对命令行参数的不正确顺序所说的话吗?因此,为什么引用很重要。让我们启用诊断输出,看看shell执行了什么:
$ set -x
# throws error
$ [ $1 != '' ] && [ $2 != '' ]
+ '[' '!=' '' ']'
bash: [: !=: unary operator expected
# no error
$ [ "$1" != '' ] && [ "$2" != '' ] || echo null vars
+ '[' '' '!=' '' ']'
+ echo null vars
null vars
更好的方法来测试未设置的变量
你看到的一个非常频繁的方法是:
if [ "x$var1" == "x" ] && [ "x$var2" == "x" ];
then
echo "both variables are null"
fi
引用Gilles:
In [ “x$1″ = x”” ], the x prefix ensures that x”$1″ cannot possibly look like an operator, and so the only way the shell can parse this test is by treating = as a binary operator.
据推测,这应该是相当便携的,因为我在/bin/sh
脚本中看到了这些。它也可以组合在一起
if [ "x${var1}${var2}" == "x" ]; then
...
fi
当然我们可以使用-z
标志,但是根据一些shell中的研究,特别是ksh88(根据Stephane Chazelas),这个标志是错误的。
也可以看看
-
Bash运算符
\[
vs\[\[
vs((