60

私はbashで発見したばかりset -uで、これまでに見られなかったいくつかのバグを見つけるのに役立ちました。しかし、デフォルト値を計算する前に、変数が定義されているかどうかをテストする必要があるシナリオもあります。これについて私が思いついた最高のものは次のとおりです。

if [ "${variable-undefined}" == undefined ]; then
    variable="$(...)"
fi

これは機能します(変数に文字列値がない場合undefined)。もっと良い方法があるのだろうか?

4

7 に答える 7

64

これは、他の回答からインスピレーションを得て、私にとって最も効果的であると私が見つけたものです。

if [ -z "${varname-}" ]; then
  ...
  varname=$(...)
fi
于 2012-07-06T20:40:11.187 に答える
34

動作しないもの:長さがゼロの文字列をテストする

未定義の文字列をテストするには、いくつかの方法があります。標準のテスト条件を使用すると、次のようになります。

# Test for zero-length string.
[ -z "$variable" ] || variable='foo'

ただし、これはでは機能しませんset -u

動作するもの:条件付き割り当て

または、条件付き割り当てを使用することもできます。これは、Bashに似た方法です。例えば:

# Assign value if variable is unset or null.
: "${variable:=foo}"

set -uBashがこの式の展開を処理する方法により、「bash:variable:unboundvariable」エラーが発生することなくこれを安全に使用できます。

于 2012-07-06T12:38:27.177 に答える
11

bash 4.2以降では、変数が設定されているかどうかを確認する明示的な方法があります。これは、-vを使用することです。質問の例は、次のように実装できます。

if [[ ! -v variable ]]; then
   variable="$(...)"
fi

http://www.gnu.org/software/bash/manual/bashref.html#Bash-Conditional-Expressionsを参照してください

変数を設定するだけで、まだ設定されていない場合は、次の行に沿って何かを行う方がよいでしょう。

variable="${variable-$(...)}"

これは、定義されているが空の変数を処理しないことに注意してください。

于 2013-06-05T17:59:03.697 に答える
5

上記の答えは動的ではありません。たとえば、「ダミー」という名前の変数をテストする方法が定義されていますか?これを試して:

is_var_defined()
{
    if [ $# -ne 1 ]
    then
        echo "Expected exactly one argument: variable name as string, e.g., 'my_var'"
        exit 1
    fi
    # Tricky.  Since Bash option 'set -u' may be enabled, we cannot directly test if a variable
    # is defined with this construct: [ ! -z "$var" ].  Instead, we must use default value
    # substitution with this construct: [ ! -z "${var:-}" ].  Normally, a default value follows the
    # operator ':-', but here we leave it blank for empty (null) string.  Finally, we need to
    # substitute the text from $1 as 'var'.  This is not allowed directly in Bash with this
    # construct: [ ! -z "${$1:-}" ].  We need to use indirection with eval operator.
    # Example: $1="var"
    # Expansion for eval operator: "[ ! -z \${$1:-} ]" -> "[ ! -z \${var:-} ]"
    # Code  execute: [ ! -z ${var:-} ]
    eval "[ ! -z \${$1:-} ]"
    return $?  # Pedantic.
}

関連:変数がBashに設定されているかどうかを確認する方法は?

于 2013-11-09T08:48:53.077 に答える
1

残念ながら[[ -v variable ]]、古いバージョンのbashではサポートされていません(少なくとも、Debian Squeezeにあるバージョン4.1.5ではサポートされていません)。

代わりに、次のようにサブシェルを使用できます。

if (true $variable)&>/dev/null; then
    variable="$(...)"
fi
于 2014-04-11T10:35:02.613 に答える
0

スクリプトの最初に、空の値で変数を定義できます

variable_undefined=""

それで

if [ "${variable_undefined}" == "" ]; then
    variable="$(...)"
fi
于 2012-07-06T12:34:33.387 に答える
0
if [ "${var+SET}" = "SET" ] ; then
    echo "\$var = ${var}"
fi

$ {var + value}がどれだけ前にサポートされているかはわかりませんが、少なくとも4.1.2までは機能します。古いバージョンには${var+ value}がなく、$ {var:+value}しかありませんでした。違いは、$ {var:+ value}は、$ varがでない文字列に設定されている場合にのみ「value」と評価され、$ {var+value}も$varが空に設定されている場合は「value」と評価されることです。ストリング。

[[-vvar]]または${var+ value}がないと、別の方法を使用する必要があると思います。おそらく、前の回答で説明したサブシェルテスト:

if ( set -u; echo "$var" ) &> /dev/null; then
    echo "\$var = ${var}
fi

シェルプロセスで「set-u」がすでにアクティブになっている場合は、「set -u」を再度必要とせずにサブシェルでもアクティブになりますが、サブシェルコマンドに含めると、親プロセスでもソリューションが機能します。 「set-u」が有効になっていません。

(「printenv」や「env」などの別のプロセスを使用して変数の存在をテストすることもできますが、その場合は、変数がエクスポートされた場合にのみ機能します。)

于 2016-03-04T00:49:55.483 に答える