Edited at

POSIXシェルで変数がセットされているか検査するイディオム

More than 3 years have passed since last update.

偶にしか使わないと忘れるので備忘録がてら。

2016-04-25 17:26

定義されている、されていないの説明が逆だったので修正しました。失礼しました。

空文字列なのか変数がセットされていないのかを区別しないなら最近のシェルなら

[ -n "$foo" ]

で検査可能。変数が非空の時にtrueになる(exit statusが0になる)。

空文字列と未定義変数を区別して、未定義変数であるかを検査したいなら

${foo+:} false

で検査可能。こちらも変数が定義されている時にtrueになる(exit statusが0になる)。

これは若干説明が必要だろうか。

まず、変数展開の1つに

${foo+hogehoge}

というのがある。これは foo が定義されていれば hogehoge 、定義されていなければ空に展開される。

${foo+:}

そこでこれは foo が定義されていれば : に展開される。 : は「何もしない」コマンドだ。引数を全て無視してただtrue(exit status 0)を返す。

ということで

${foo+:} false

foo が定義されてる時には : false になり、実行すると : が引数の false を無視してtrueを返す。

foo が定義されていなければ ${foo+:} は空に展開されるので ${foo+:} falsefalse に展開される。 false はfalse(exit status 1)を返すコマンドだ。

これでとりあえず検査は出来るがパッと見どっちがどっちか分からないのでちゃんとコメントを残そう。

## 分岐

if ${foo+:} false; then
# fooが定義されている時
else
# fooが定義されていない時
fi

## 定義されていない時のみ何かしたい時は `!` を使って否定する。
if ! ${foo+:} false; then
# fooが定義されていない時
fi

以上