web-dev-qa-db-ja.com

シェルスクリプトで変数が空かどうかのテスト

変数が空かどうかをテストするために、次のテクニックが多くの異なるシェルで何度も使用されるのを見てきました。

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

これをより標準的なif [ -z "$1" ]よりも使用する利点はありますか?移植性の問題でしょうか?

27
rahmu

一部の歴史的シェルは、_[ -n = "" ]_の最初のオペランドが演算子のように見え、_=_のように混乱し、これを_[ -n = ]_として解析するか、構文エラーを引き起こす非常に単純なパーサーを実装しました。 _[ "x$1" = x"" ]_では、x接頭辞により_x"$1"_が演算子のように見えないことが保証されるため、シェルがこのテストを解析できる唯一の方法は_=_を二項演算子。

すべての最新のシェル、およびまだ動作しているほとんどの古いシェルでさえ、 POSIXルール に従います。これは、最大4ワードのすべてのテスト式を正しく解析することを要求します。したがって、_[ -z "$1" ]_は、_$1_が空であるかどうかをテストする適切な方法です、および_[ "$x" = "$y" ]_は、 2つの変数の等価性をテストします。

一部の現在のシェルでも長い式と混同される可能性があり、実際にはいくつかの式があいまいなので、_-a_および_-o_演算子を使用して長いブールテストを作成するのではなく、代わりに_[_およびシェル独自の_&&_および_||_ブール演算子。

http://www.mpi-inf.mpg.de/~uwe/lehre/unixffb/quoting-guide.html によると、-zテストは一部の実装では安全ではありません、おそらく"-o a=a"のような「興味深い」文字列がテストされる場合。

5

上記のテストでは、「set -u」または「set -o nounset」を使用して実行した場合もエラーが発生します。

空の変数をチェックするより安定した方法は、 パラメータ展開 を使用することです。

MYVAR = $ {MYVAR:-"悪い値"}

この方法は、従来のボーンシェル、ksh、bashで機能します。

3
Scott Hoffman
    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
0
aslam mohammed