LAB_FLAG=onが現在のBashに設定されている。
値を空文字へ変更するのではなく、変数自体を未設定にする。
適切なコマンドはどれか。
unsetは変数の定義を取り除く。空文字の代入とは、設定状態を調べたときの結果が異なる。
詳細解説
LAB_FLAG=値を空文字にするが、変数は設定済みのまま残る。
空文字を表示することと、変数が未設定であることは別である。LAB_FLAG=の後は[[ -v LAB_FLAG ]]が真になり、設定済みのままと分かる。値を表示するだけでは未設定との違いが見えにくい。
unset LAB_FLAGunsetは指定したシェル変数を未設定にする。
通常の変更可能なスカラー変数では、unset後の[[ -v LAB_FLAG ]]は偽になる。定義を取り除くので、空文字を代入した状態との違いを設定状態で確認できる。
export LAB_FLAG変数にexport属性を付ける操作であり、削除しない。
既存のonという値にexport属性を付ける。値は残り、設定状態の検査も真のままである。子への継承を変える操作を、親からの削除と混同しない。
set LAB_FLAG位置パラメータを設定し、LAB_FLAGという変数は削除しない。
set LAB_FLAGは文字列LAB_FLAGを$1へ設定する。名前付き変数LAB_FLAGのonという値は残る。位置パラメータと同名の変数は別の領域として確認する。
実際に確かめる
一時的な検証環境で実行できる例です。
LAB_FLAG=
if [[ -v LAB_FLAG ]]; then printf 'empty=set\n'; else printf 'empty=unset\n'; fi
printf 'empty/default=<%s>\n' "${LAB_FLAG-fallback}"
printf 'empty/colon=<%s>\n' "${LAB_FLAG:-fallback}"
unset LAB_FLAG
if [[ -v LAB_FLAG ]]; then printf 'removed=set\n'; else printf 'removed=unset\n'; fi
printf 'removed/default=<%s>\n' "${LAB_FLAG-fallback}"参考にした公式資料
期待される結果
empty=set
empty/default=<>
empty/colon=<fallback>
removed=unset
removed/default=<fallback>理解のポイント
- 未設定と空文字の違い
- unsetの役割
- [[ -v ]]による設定状態確認
確認時の注意
- 確認環境: Bash 5.2。通常の変更可能なスカラー変数を、新規Bashプロセス内で検証する。
- 通常の変更可能なスカラー変数の例を新規Bashで検証する。readonly属性を付けた変数などの別条件を混ぜない。
- 表示されるempty=setとremoved=unsetを比べ、空文字の有無だけで未設定を判定しない。デフォルト展開の比較は、元の問題の区別を確認する補助例である。
基礎のおさらい
空と未設定を観測で区別する
空文字の代入後も-vの判定は真、unset後は偽になる。単なる値の表示ではどちらも空に見えるため、設定状態そのものを検査する。
デフォルト値展開のコロン
${LAB_FLAG-fallback}は未設定の場合だけfallbackを使い、${LAB_FLAG:-fallback}は未設定または空の場合にfallbackを使う。コロンの有無が区別する条件を変える。
状態を変える対象を確認する
代入は値、exportは継承属性、setの引数は位置パラメータ、unsetは定義を扱う。この問題では現在の通常変数の定義が対象になる。