📐

【シェルスクリプト】未定義変数の扱いについてのメモ

2024/06/19に公開2

概要

シェルスクリプトにおいては、未定義の変数であっても処理が行われる動作になるようです。この未定義の変数を参照した際に、どのような結果になるか少し気になったので今回メモ書きします。

前提

  • 今回の動作確認は、Macのzshを使用して行なっています。(bashでも同じ結果になると思いますが)

確認内容

【文字列】

以下の通り、未定義の変数と空文字を比較したところ、結果はtrueとなりました。

empty_string=""
if [[ $empty_string = $undefined_val ]]; then
  echo "equal"
else
  echo "not equal"
fi

【数値計算】

以下の通り未定義の変数を数式に設定したところエラー1 + : syntax error: operand expected (error token is " ")になりました。空文字と同値となる動作になります。

echo $((1 + $undefined_val))

【配列】

以下の通り未定義の変数に対して要素数を取得したところ、結果0となりました。空配列の扱いになります。

echo ${#undefined_val[*]}

一応、以下のように空配列と差分を取ってみたところ、差分はありませんでした。

array_empty=()
echo ${array_empty[@]} ${undefined_val[@]} | tr ' ' '\n' | sort | uniq -u

その他参考

Discussion

ko1nksmko1nksm

以下の通り、未定義の変数と空文字を比較したところ、結果はtrueとなりました。

empty_string=""
if [ $empty_string = $undefined_val ]; then
  echo "equal"
else
  echo "not equal"
fi

これは [ ... ] を使用しており変数をダブルクォートしてないため次のように解釈されます。これは文字列の長さがあるか?という意味になり、変数の比較が行われていません。

if [ = ]; then
  echo "equal"
else
  echo "not equal"
fi

そのため、以下のコードでは 未定義と空文字は not equal という結果になります。

empty_string=""
if [ $empty_string != $undefined_val ]; then
  # [ != ] と解釈される、文字列の長さがあるので not equal となる
  echo "not equal"
else
  echo "equal"
fi

変数をダブルクォートするか、[[ ... ]] を使用してください。

if [ "$empty_string" = "$undefined_val" ]; then
# または
if [[ $empty_string = $undefined_val ]]; then