测试shell脚本中变量是否为空


27

我已经看到以下技术在许多不同的shell上多次使用,以测试变量是否为空:

if [ "x$1" = "x" ]; then 
    # Variable is empty
fi

与更规范的用法相比,使用此方法有什么好处if [ -z "$1" ]吗?可能是可移植性问题吗?

Answers:


17

一些历史性的Shell实现了一个非常简单的解析器,该解析器可能会[ -n = "" ]因第一个操作数=看起来像运算符的位置而感到困惑,并且会将其解析为[ -n = ]或导致语法错误。在中[ "x$1" = x"" ]x前缀确保x"$1"不能看起来像运算符,因此shell解析此测试的唯一方法是将其=视为二进制运算符。

所有现代Shell,甚至仍在运行的大多数较旧的Shell,都遵循POSIX规则,该规则要求正确解析最多4个单词的所有测试表达式。因此[ -z "$1" ]是测试的一个适当的方式,如果$1是空的,并且[ "$x" = "$y" ]是测试两个变量的平等之有道。

即使是当前的某些Shell也可能会与较长的表达式混淆,而实际上有些表达式是模棱两可的,因此请避免使用-aand -o运算符构造较长的布尔测试,而应使用[对shell自身&&||布尔运算符的单独调用。


3
这不仅是历史性的炮弹。基于sh某些商业Unices的某些ksh88 仍然存在此问题。有关详细信息,请参见此处
斯特凡Chazelas

该语句是错误的:[ -z "$1" ]是测试是否$1为空的正确方法sh -c '[ -z "$1" ]' ''; sh -c '[ -z "$1" ]'-两者都返回0,但在第二种情况下$1不能为空,因为它不存在。
mikeserv


3

如果您使用“ set -u”或“ set -o nounset”运行,上述测试也会导致错误

检查空变量的更稳定方法是使用参数扩展

MYVAR = $ {MYVAR:-“ Bad Value”}

此方法适用于传统的bourne shell,ksh和bash。


2
我相信这是这样写的-> M = $ {M:-“ Bad Value”}
Gyan

0
    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

3
嗨!我不确定这如何回答这个问题,该问题询问为什么要使用=vs -z,而现在要怎么使用。
dhag 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.