bash変数が空かどうかを判断する方法は?


回答:


1053

変数が設定されていないか、空の文字列( "")に設定されている場合、これはtrueを返します。

if [ -z "$VAR" ];

14
変数が ""の値に設定されている場合は含まれますか?
ブレント

11
はい、そうです... "-z"は長さゼロの文字列をテストします。
デビッドZ

91
if [ ! -z "$VAR" ];
アーロンコプリー

263
-z-n if [ -n "$VAR" ];
フェリペアルバレス

19
二重引用符は、変数が分割されないようにします。$varコマンドラインの単純なものは、空白によってパラメータのリストに分割されますが、"$var"常に1つのパラメータにすぎません。多くの場合、変数を引用することは良い習慣であり、(特に)空白を含むファイル名につまずくことを防ぎます。例:実行後a="x --help"、try- cat $aのヘルプページが表示されcatます。その後、試してくださいcat "$a"-それは(通常)言うでしょうcat: x --help: No such file or directory。要するに、早く引用し、頻繁に引用すれば、後悔することはほとんどありません。
Score_Under 14

247

Bashでは、サポートしていないシェルへの移植性に関心がない場合は、常に二重括弧構文を使用する必要があります。

次のいずれか:

if [[ -z $variable ]]
if [[ -z "$variable" ]]
if [[ ! $variable ]]
if [[ ! "$variable" ]]

Bashでは、二重角括弧を使用して、引用符は必要ありません。あなたは、変数のためのテストを簡素化することができないに値が含まれています。

if [[ $variable ]]

この構文はkshと互換性があります(少なくともksh93、とにかく)。純粋なPOSIXまたはshやdashなどの古いBourneシェルでは機能しません。

二重角括弧と単一角括弧の違いの詳細については、ここでの私の答えBashFAQ / 031を参照しください。

変数が明確に設定されているかどうかをテストすることができます(空の文字列とは異なる):

if [[ -z ${variable+x} ]]

ここで、「x」は任意です。

変数がnullであるが設定解除されていないかどうかを知りたい場合:

if [[ -z $variable && ${variable+x} ]]

1
それif [[ $variable ]]は私にとってはうまく機能しset -u、他の提案されたソリューションのいずれかで必要とされたものさえ必要としませんでした。
Teemu Leisti

3
これは受け入れられている答えよりも優れていると思います。
13

2
移植性のない機能を推奨してもメリットがないのに、なぜ推奨しないのですか?
アラステアアーバイン14年

19
@AlastairIrvine:私は私の答えの最初の文で移植性に言及し、質問のタイトルと本文は、単語「バッシュ」を含むと質問がタグ付けされたbashのを、ダブルブラケット構造が提供明確な利点を多くの方法で。一貫性と保守性の理由から、ブラケットスタイルを混在させることはお勧めしません。最大で最小の共通分母の移植性が必要な場合shは、Bashの代わりに使用します。提供する機能を強化する必要がある場合は、Bashを使用して完全に使用してください。
デニスウィリアムソン14年

2
@BrunoBronosky:編集を元に戻しました。;最後に要件はありません。then全くセミコロンなしに次の行にすることができます。
デニスウィリアムソン

230

bash(およびPOSIX互換シェル)の変数は、次の3つの状態のいずれかになります。

  • 設定解除
  • 空の文字列に設定
  • 空でない文字列に設定

ほとんどの場合、変数が空でない文字列に設定されているかどうかを知るだけで済みますが、未設定と空の文字列への設定を区別することが重要な場合があります。

以下は、さまざまな可能性をテストする方法の例であり、bashまたはPOSIX互換シェルで機能します。

if [ -z "${VAR}" ]; then
    echo "VAR is unset or set to the empty string"
fi
if [ -z "${VAR+set}" ]; then
    echo "VAR is unset"
fi
if [ -z "${VAR-unset}" ]; then
    echo "VAR is set to the empty string"
fi
if [ -n "${VAR}" ]; then
    echo "VAR is set to a non-empty string"
fi
if [ -n "${VAR+set}" ]; then
    echo "VAR is set, possibly to the empty string"
fi
if [ -n "${VAR-unset}" ]; then
    echo "VAR is either unset or set to a non-empty string"
fi

以下は同じものですが、便利な表形式です。

                        +-------+-------+-----------+
                VAR is: | unset | empty | non-empty |
+-----------------------+-------+-------+-----------+
| [ -z "${VAR}" ]       | true  | true  | false     |
| [ -z "${VAR+set}" ]   | true  | false | false     |
| [ -z "${VAR-unset}" ] | false | true  | false     |
| [ -n "${VAR}" ]       | false | false | true      |
| [ -n "${VAR+set}" ]   | false | true  | true      |
| [ -n "${VAR-unset}" ] | true  | false | true      |
+-----------------------+-------+-------+-----------+

${VAR+foo}場合コンストラクトは、空の文字列に展開されますVAR設定されていないかにfooあればVAR何も設定されている(空の文字列を含みます)。

${VAR-foo}構築物の値に展開VARし(空の文字列に設定含む)場合foo解除場合。これは、ユーザーがオーバーライド可能なデフォルトを提供するのに役立ちます(たとえば、変数が何かに設定されていない限り、${COLOR-red}使用するようにred指示しますCOLOR)。

[ x"${VAR}" = x ]変数が設定されていないか、空の文字列に設定されているかどうかをテストするためによく推奨される理由は、[コマンドの実装(別名test)にバグがあるためです。VARがのようなものに設定されている場合、最初の引数が文字列ではなく演算子として誤って解釈されるため、-n一部の実装は与えられ[ "${VAR}" = "" ]たときに間違った動作をします。[-n


3
空の文字列に設定された変数のテストも、を使用して実行でき[ -z "${VAR-set}" ]ます。
-nwellnhof

@nwellnhof:ありがとう!簡潔な構文を使用するように回答を更新しました。
リチャードハンセン

最初の構造と最後の構造の違いは何ですか?これらは両方とも「VARが設定されていないか、空でない文字列に設定されています」に対応しています。
ファヒームミタ

1
@FaheemMitha:それはあなたのせいではない-私の答えは読みにくい。答えをより明確にするために、テーブルを追加しました。
リチャードハンセン

2
設定解除チェックは信頼できません。ユーザーが呼び出した、set -uまたはset -o nounsetbashの場合、テストの結果は「bash:VAR:unbound variable」というエラーになります。より確実な設定解除チェックについては、stackoverflow.com / a / 13864829を参照してください。変数がnullであるか未設定であるかをチェックします[ -z "${VAR:-}" ]。変数が空でないかどうかの私のチェックは[ "${VAR:-}" ]です。
ケビン・ジン

38

-z 最良の方法です。

私が使用した別のオプションは変数を設定することですが、別の変数で上書きすることができます。例えば

export PORT=${MY_PORT:-5432}

$MY_PORT変数が空の場合はPORT5432に設定され、それ以外の場合はPORTの値が設定されますMY_PORT。構文にはコロンとダッシュが含まれていることに注意してください。


今日偶然これを見つけました、そしてそれはまさに私が欲しかったものでした。ありがとう!set -o nounset一部のスクリプトでは許容する必要があります。
オペロ

24

set-emptyとunsetステータスのケースを区別したい場合は、bashの-uオプションを見てください。

$ set -u
$ echo $BAR
bash: BAR: unbound variable
$ [ -z "$BAR" ] && echo true
bash: BAR: unbound variable
$ BAR=""
$ echo $BAR

$ [ -z "$BAR" ] && echo true
true

8

私が見た代替[ -z "$foo" ]は次のとおりですが、なぜ人々がこの方法を使用するのか分かりません、誰もが知っていますか?

[ "x${foo}" = "x" ]

とにかく未設定の変数を(by set -uまたはset -o nounset)許可しない場合は、これらのメソッドの両方で問題が発生します。これには簡単な修正があります。

[ -z "${foo:-}" ]

注:これにより、変数は未定義のままになります。


3
代替についてのコメントがあります-zpubs.opengroup.org/onlinepubs/009695399/utilities/test.htmlが。基本的に、これはの代わりになるものではありません-z。むしろ、$fooメタキャラクターで始まる、[またはtest混乱する可能性のあるものに展開される可能性があるケースを処理します。最初に任意の非メタキャラクターを置くと、その可能性がなくなります。
ジェームズ・スニーリンガー

6

この質問、変数が空の文字列であり、そのための最良の回答がすでに与えられているかどうかを確認する方法を尋ねます
しかし、PHPでのプログラミングに合格した後、ここに着きました。実際に検索していたのは、bashシェルで動作するphp空の関数のようなチェックでした。
答えを読んだ後、私はbashで適切に考えていないことに気付きましたが、その瞬間、PHPの空のような関数は私のbashコードでとても便利だったでしょう。
私はこれが他の人にも起こりうると思う

ので、phpマニュアルに従ってbashのphp empty関数を変換することにしました:
変数が存在しない場合、またはその値が次のいずれかである場合、変数は空と見なされます。

  • ""(空の文字列)
  • 0(整数として0)
  • 0.0(フロートとして0)
  • "0"(文字列として0)
  • 空の配列
  • 宣言されているが値のない変数

もちろん、nullfalseのケースはbashで変換できないため、省略されます。

function empty
{
    local var="$1"

    # Return true if:
    # 1.    var is a null string ("" as empty string)
    # 2.    a non set variable is passed
    # 3.    a declared variable or array but without a value is passed
    # 4.    an empty array is passed
    if test -z "$var"
    then
        [[ $( echo "1" ) ]]
        return

    # Return true if var is zero (0 as an integer or "0" as a string)
    elif [ "$var" == 0 2> /dev/null ]
    then
        [[ $( echo "1" ) ]]
        return

    # Return true if var is 0.0 (0 as a float)
    elif [ "$var" == 0.0 2> /dev/null ]
    then
        [[ $( echo "1" ) ]]
        return
    fi

    [[ $( echo "" ) ]]
}



使用例:

if empty "${var}"
    then
        echo "empty"
    else
        echo "not empty"
fi



デモ:
次のスニペット:

#!/bin/bash

vars=(
    ""
    0
    0.0
    "0"
    1
    "string"
    " "
)

for (( i=0; i<${#vars[@]}; i++ ))
do
    var="${vars[$i]}"

    if empty "${var}"
        then
            what="empty"
        else
            what="not empty"
    fi
    echo "VAR \"$var\" is $what"
done

exit

出力:

VAR "" is empty
VAR "0" is empty
VAR "0.0" is empty
VAR "0" is empty
VAR "1" is not empty
VAR "string" is not empty
VAR " " is not empty

bashロジックでは、この関数のゼロのチェックはサイドの問題を引き起こす可能性があると述べましたが、この関数を使用する人は誰でもこのリスクを評価し、最初のチェックのみを残してこれらのチェックをカットすることを決定する必要があります。


関数の内部empty-なぜ[[ $( echo "1" ) ]] ; return単純に書く代わりに書いたのですreturn 1か?
ドール

5

if-thenと-z全体は不要です。

["$ foo"] && echo "fooは空ではありません"
["$ foo"] || echo "fooは確かに空です"

3
fooはスペースのみが含まれている場合、それは失敗します
ブライアン

2
オプションとして解釈されるため、fooがダッシュで始まる場合も一部のシェルで失敗します。Solaris上の例のkshzshのbashは問題ありません、SHおよび/ binに/テストは失敗します
KTF

4

これは、$ FOOが設定されて空の場合に当てはまります。

[ "${FOO+x}" = x ] && [ -z "$FOO" ]

4

個人的には、より明確な確認方法を好む:

if [ "${VARIABLE}" == "" ]; then
  echo VARIABLE is empty
else
  echo VARIABLE is not empty
fi

1
一部のシェルは二重等号を受け入れません。
デニスウィリアムソン

1
質問はbashについてでした。私はbashを使用しています。私にとってはうまくいきます。正確にあなたは何について話しているのですか?
フェディルRYKHTIK

2
Bashを使用している場合は、二重角括弧を使用する必要があります。私の以前のコメントは、あなたの答えを読んで別のシェルを使用しているかもしれない人のための事実の簡単な声明でした。
デニスウィリアムソン

単一角括弧は、この場合にはOKです、参照してくださいserverfault.com/questions/52034/...を
ルカBorrione


4

私の5セント:if ...、これよりも短い構文もあります:

VALUE="${1?"Usage: $0 value"}"

引数が指定されている場合、この行はVALUEを設定し、エラーの場合にスクリプト行番号を先頭に追加したエラーメッセージを出力します(スクリプトの実行を終了します)。

別の例はabs-guideにあります(«例10-7»を検索してください)。


0

正確な答えではありませんが、このトリックに遭遇しました。探している文字列が「コマンド」からのものである場合、実際にコマンドをenvに保存できます。変数を使用し、ifステートメントに対して毎回実行する場合、括弧は不要です!

たとえば、次のコマンドは、debianを使用しているかどうかを判断します。

grep debian /proc/version

完全な例:

IS_DEBIAN="grep -i debian /proc/version"

if $IS_DEBIAN; then
  echo 'yes debian'
else
  echo 'non debian'
fi

したがって、これは空の文字列をチェックする間接的な方法(毎回実行する)に似ています(たまたまコマンドからのエラー応答をチェックしていますが、空の文字列を返すこともあります)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.