Answers:
一些历史性的Shell实现了一个非常简单的解析器,该解析器可能会[ -n = "" ]
因第一个操作数=
看起来像运算符的位置而感到困惑,并且会将其解析为[ -n = ]
或导致语法错误。在中[ "x$1" = x"" ]
,x
前缀确保x"$1"
不能看起来像运算符,因此shell解析此测试的唯一方法是将其=
视为二进制运算符。
所有现代Shell,甚至仍在运行的大多数较旧的Shell,都遵循POSIX规则,该规则要求正确解析最多4个单词的所有测试表达式。因此[ -z "$1" ]
是测试的一个适当的方式,如果$1
是空的,并且[ "$x" = "$y" ]
是测试两个变量的平等之有道。
即使是当前的某些Shell也可能会与较长的表达式混淆,而实际上有些表达式是模棱两可的,因此请避免使用-a
and -o
运算符构造较长的布尔测试,而应使用[
对shell自身&&
和||
布尔运算符的单独调用。
[ -z "$1" ]
是测试是否$1
为空的正确方法。sh -c '[ -z "$1" ]' ''; sh -c '[ -z "$1" ]'
-两者都返回0,但在第二种情况下$1
不能为空,因为它不存在。
根据http://www.mpi-inf.mpg.de/~uwe/lehre/unixffb/quoting-guide.html,该-z
测试在某些实现中是不安全的,大概是在"-o a=a"
测试了“有趣的”字符串时。
function isBlank {
valueNoSpaces=$(echo "$@" | tr -d ' ')
if [ "$valueNoSpaces" == null ] || [ -z "$valueNoSpaces" ]
then
echo true ;
else
echo "" ;
fi
}
#Test
if [ $(isBlank " ") ]
then
echo "isBlank \" \" : it's blank"
else
echo " isBlank \" \": it is not blank"
fi
if [ $(isBlank "abc") ]
then
echo "isBlank \"abc\" : it's blank"
else
echo "isBlank \"abc\" :it is not blank"
fi
if [ $(isBlank null) ]
then
echo "isBlank null : it's blank"
else
echo "isBlank null : it is not blank"
fi
if [ $(isBlank "") ]
then
echo "isBlank \"\" : it's blank"
else
echo "isBlank \"\" : it is not blank"
fi
#Result
isBlank " " : it's blank
isBlank "abc" :it is not blank
isBlank null : it's blank
isBlank "" : it's blank
=
vs -z
,而现在要怎么使用。
sh
某些商业Unices的某些ksh88 仍然存在此问题。有关详细信息,请参见此处。