バインドされていない変数を重複なく処理する方法は?

バインドされていない変数を重複なく処理する方法は?

コマンド終了状態を処理するには、次の一般的なパターンを考慮してください。

if COMMAND; then
    echo success
else
    echo failure
fi

同じ変数割り当て(与えられたset -o nounset)を使用しても機能しません。

$ if foo="$no_such_variable"; then echo success; else echo failure; fi
bash: no_such_variable: unbound variable

変数置換の確認また、動作しません。

$ if foo="${no_such_variable:?}"; then echo success; else echo failure; fi
bash: no_such_variable: parameter null or not set

ステートメント内で割り当ての戻りコードをキャプチャする方法はありますかifif [[ $# -eq N ]]各割り当て自体で問題をキャッチするのではなく、そのステートメントをスクリプトの残りの部分にあるすべてのパラメータ割り当てと組み合わせるので、標準的な回避策を避けたいと思います。

これはPythonモードと似ていますif (foo := bar()):

答え1

変数を設定しない組み込みテストを中心に何かを構築することもできますtest -v no_such_variable。たとえば、関数はsetvarこのテストを実行し、通常の場合にのみ割り当てることができます。

set -o nounset
setvar(){
  declare -n var=$1 # -n is like ${!var} but for lvalue too
  declare value=$2
  [ -v ${value} ] && var="${!value}"
}
if setvar foo no_such_variable
then echo success
else echo failure
fi

答え2

ifステートメントから割り当ての戻りコードをキャプチャする方法はありますか?

ここで役に立つ終了ステータスを見ることができるかもしれません。

set -u/以下の変数拡張nounset機能は${var?message}次のとおりです。シェル終了変数が設定されていない場合。その後、スクリプトは実行されなくなったため、スクリプトで終了値を見ることはできません。

ジョブにコマンド置換が含まれている場合、終了ステータスはそこから出ます。それ以外の場合、割り当ては成功します。

変数が設定されていないことを確認するには、代替値拡張を使用する必要があります。${var+string}変数が設定されている場合(その値を使用せず)、値が指定された文字列に拡張され、設定されていない場合は何も拡張されません。

だから

if [ "${var+set}" ]; then
    foo="$var"
    echo '$var copied to $foo'
else
    echo '$var is unset'
fi

または、nounsetコピーが失敗しないように無効にしてください。

set +u
foo="$var"
echo '$var copied to $foo'

ただし、NULL以外の値が存在することを確認する必要がある場合は、これを別々に実行する必要があります。

関連情報