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


27

変数が空かどうかをテストするために、さまざまなシェルで次の手法が何度も使用されているのを見てきました。

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

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

回答:


17

いくつかの歴史的なシェル[ -n = "" ]は、最初のオペランドが=演算子のように見える場所などによって混乱する可能性のある非常に単純なパーサーを実装し、これを[ -n = ]構文エラーまたは構文エラーを引き起こす可能性があります。では[ "x$1" = x"" ]xプレフィックスx"$1"によって演算子のように見えないことが保証されるため、シェルがこのテストを解析できる唯一の方法は=、バイナリ演算子として扱うことです。

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

いくつかの現在のシェルでさえ長い式と混同される可能性があり、いくつかの式は実際にはあいまいです。そのため、-aand -o演算子を使用して長いブールテストを作成するのを避け、代わり[にシェルの独自の呼び出し&&||ブール演算子を使用してください。


3
歴史的な貝殻だけではありません。いくつshかの商用Unices上のksh88ベースのsにはまだ問題があります。詳細はこちらをご覧ください。
ステファンシャゼル

この文は誤りです。if が空の[ -z "$1" ]場合、テストする適切な方法です$1sh -c '[ -z "$1" ]' ''; sh -c '[ -z "$1" ]'-両方とも0を返しますが、2番目の場合$1は存在しないため空にできません。
mikeserv 14


3

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

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

MYVAR = $ {MYVAR:-"Bad Value"}

この方法は、kshおよびbashと同様に、従来のbourneシェルでも機能します。


2
:> M = $ { - "不正な値" M - }私はこれは次のように書かれていると信じて
ギャン

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
こんにちは!私はこれが尋ねる質問に答える方法がわからないんだけど、なぜ使用する方法=と比べ-z、今どのようにして、。
dhag
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.