我见过在许多不同的 shell 上多次使用以下技术来测试变量是否为空:
if [ "x$1" = "x" ]; then
# Variable is empty
fi
与更规范的方法相比,使用它有什么优势吗if [ -z "$1" ]
?这可能是一个可移植性问题吗?
答案1
[ -n = "" ]
一些历史 shell 实现了一个非常简单的解析器,它可能会因第一个操作数看起来像运算符之类的事情而感到困惑=
,并将其解析为[ -n = ]
或导致语法错误。在 中[ "x$1" = x"" ]
,x
前缀确保x"$1"
不可能看起来像运算符,因此 shell 解析此测试的唯一方法是将其视为=
二元运算符。
所有现代炮弹,甚至大多数仍在运行的较旧炮弹,都遵循POSIX 规则它要求正确解析最多 4 个单词的所有测试表达式。所以[ -z "$1" ]
$1
是测试是否为空的正确方法,并且[ "$x" = "$y" ]
是测试两个变量相等的正确方法。
即使某些当前的 shell 也可能会与较长的表达式混淆,并且一些表达式实际上是不明确的,因此请避免使用-a
and-o
运算符来构造较长的布尔测试,而是使用单独的调用[
shell 自己的&&
and||
布尔运算符。
答案2
根据http://www.mpi-inf.mpg.de/~uwe/lehre/unixffb/quoting-guide.html,-z
测试是在某些实现中不安全"-o a=a"
,大概是在测试“有趣的”字符串时。
答案3
如果使用“set -u”或“set -o nounset”运行,上述测试也会导致错误
检查空变量的更稳定的方法是使用参数扩展:
MYVAR=${MYVAR:-"错误价值"}
此方法适用于传统的 bourne shell、ksh 和 bash。
答案4
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