set -Euopipelinefailを使用するときに変数の存在をどのように確認しますか? [コピー]

set -Euopipelinefailを使用するときに変数の存在をどのように確認しますか? [コピー]

次のコードを使用して、変数が空でなく正しく機能していることを確認します。

VAR=(var1 var2 var3)

chec_var() {
for item in "${@}"; do
if [ -z "${!item}" ]; then
  returncode=1
  break
else
  returncode=0
fi
done
}

all_vars() {
if chec_var "${VAR[@]}"; then
  if [[ ${returncode} -gt 0 ]]; then
    echo "error"
    exit 1
  else
    echo "OK"
  fi
fi
}

all_vars

スクリプトの最後に set -Euopipelinefail を追加すると問題が発生します。
変数の1つが存在しない場合よりも、次のエラーが発生します。
/script line number: !item unbound Variable が
パイプライン障害のメッセージの代わりに「エコーエラー」を表示する必要があります。

別の場合は、すべての変数が存在するときにループを通過してすべての変数を確認するのではなく、最初の変数だけをチェックして
「echo OK」と言います。質問:ここで私が何を間違っているのですか? -Euopipelinefailが有効になっているときにすべての変数を繰り返してすべてをチェックして「OK」を表示するにはどうすればよいですか?





Pipelinefailを使用して変更されたスクリプトは次のとおりです。

VAR=(var1 var2 var3)

chec_var() {
for item in "${@}"; do
if [ -z "${!item}" ]; then
  return 1
  break
else
  return 0
fi
done
}

all_vars() {
if chec_var "${VAR[@]}"; then
  if [[ ${returncode} -gt 0 ]]; then
    echo "error"
    exit 1
  else
    echo "OK"
  fi
fi
}

set -Euo pipefail

all_vars

ベストアンサー1

Bashでこれを行う1つの方法は次のとおりです。

if declare -p variable >&/dev/null ; then
  echo "variable exists"
else
  echo "variable does not exist"
if

declare -p変数が存在する場合は終了コード 0 が返され、存在しない場合は終了コード 1 が返されます。 stdout と stderr のリダイレクトは、出力を見たくなく、変数が存在するかどうかをテストするだけです。

ただし、ほとんどの場合、変数がnullかどうかをテストするだけで十分です(つまり[ -z "$variable" ]、nullではなく反転テストを使用[ -n "$variable" ])。

おすすめ記事