web-dev-qa-db-ja.com

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

Bashの変数が空( "")であるかどうかを判断する最良の方法は何ですか?

私はif [ "x$variable" = "x" ]

正しい方法ですか? (もっと簡単なものがあるはずです)

784
Brent

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

if [ -z "$VAR" ];
1075
duffbeer703

Bashでは、それをサポートしていないシェルへの移植性に関心がない場合は、常にダブルブラケット構文を使用する必要があります。

次のいずれか:

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

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

if [[ $variable ]]

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

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

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

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

「x」は任意です。

変数がnullであるが未設定ではないかどうかを知りたい場合:

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

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の値に展開されます。これは、ユーザーが上書き可能なデフォルトを提供するのに役立ちます(たとえば、変数redが何かに設定されていない限り、_${COLOR-red}_はCOLORを使用するよう指示します)。

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

239
Richard Hansen

-zが最善の方法です。

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

export PORT=${MY_PORT:-5432}

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

38
Rory

セットが空の状態とセットされていない状態のケースを区別したい場合は、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
24
MikeyB

私が[ -z "$foo" ]に見た別の方法は次のとおりですが、なぜこの方法を使用するのかわかりません。

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

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

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

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

8
errant.info

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

phpマニュアル によると:
変数が存在しない場合、またはその値が次のいずれかである場合、その変数は空であると見なされます。

  • ""(空の文字列)
  • 0 (0 as an integer)
  • 0.0(フロートとして0)
  • "0"(文字列として0)
  • 空の配列
  • 宣言された変数、ただし値なし

もちろんnullおよびfalseの場合は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ロジックでは、この関数のゼロのチェックは副次的な問題を引き起こす可能性があると述べたため、この関数を使用する人は誰でもこのリスクを評価し、おそらく最初のチェックのみを残してそれらのチェックをオフにすることを決定する必要があります。

6
Luca Borrione

私の5セント:if ...よりも短い構文もあります。これは次のとおりです。

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

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

別の例は abs-guide ("例10-7"を検索)にあります。

5
gluk47

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

 ["$ foo"] && echo "foo is not empty" 
 ["$ foo"] ||エコー "fooは確かに空です" 
5

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

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

duffbeer7 のソリューションのワンライナー拡張:

#! /bin/bash
[ -z "$1" ] || some_command_that_needs_$1_parameter
4
andrej

個人的には、より明確なチェック方法を好む:

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

正確な答えではありませんが、このトリックに遭遇しました。探している文字列が「コマンド」からのものである場合は、実際にコマンドを環境に保存できます。変数を使用して、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

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

0
rogerdpack