Bash シェル スクリプトで文字列が定義されていないかどうかを確認する方法 質問する

Bash シェル スクリプトで文字列が定義されていないかどうかを確認する方法 質問する

ヌル文字列をチェックしたい場合は次のようにします

[ -z $mystr ]

しかし、変数が定義されているかどうかを確認したい場合はどうすればよいでしょうか? それとも、Bash スクリプトでは区別がないのでしょうか?

ベストアンサー1

あなたが求めている答えは、(明示されていなくても)次の言葉で暗示されていると思います。ヴィンコ答えただし、単純には表記されません。VAR が設定されているが空であるか、設定されていないかを区別するには、次を使用できます。

if [ -z "${VAR+xxx}" ]; then echo "VAR is not set at all"; fi
if [ -z "$VAR" ] && [ "${VAR+xxx}" = "xxx" ]; then echo "VAR is set but empty"; fi

おそらく、2 行目の 2 つのテストを次のように 1 つに結合できます。

if [ -z "$VAR" -a "${VAR+xxx}" = "xxx" ]; then echo "VAR is set but empty"; fi

ただし、Autoconf のドキュメントを読むと、用語を ' -a' で結合することは推奨されておらず、 と組み合わせて個別の単純なテストを使用することが推奨されていることがわかります&&。問題があるシステムに遭遇したことはありません。これは、以前は問題がなかったという意味ではありません (ただし、遠い昔にはそれほど珍しくなかったとしても、今日ではおそらく非常にまれです)。

これらの詳細とその他の関連情報は、シェルパラメータの拡張testまたは[コマンドと条件式Bash マニュアルに記載されています。


最近、この回答について次のような質問がメールで寄せられました。

2つのテストを使用していますが、2番目のテストはよく理解できますが、最初のテストは理解できません。より正確に言うと、変数拡張の必要性が理解できません。

if [ -z "${VAR+xxx}" ]; then echo "VAR is not set at all"; fi

これなら同じことが達成されるのではないでしょうか?

if [ -z "${VAR}" ]; then echo "VAR is not set at all"; fi

もっともな質問です。答えは「いいえ、よりシンプルな代替案では同じことは起こりません」です。

テストの前にこれを書いたとします:

VAR=

あなたのテストでは「VAR はまったく設定されていません」と表示されますが、私のテストでは (何もエコーしないので暗黙的に)「VAR は設定されていますが、その値は空である可能性があります」と表示されます。次のスクリプトを試してください。

(
unset VAR
if [ -z "${VAR+xxx}" ]; then echo "JL:1 VAR is not set at all"; fi
if [ -z "${VAR}" ];     then echo "MP:1 VAR is not set at all"; fi
VAR=
if [ -z "${VAR+xxx}" ]; then echo "JL:2 VAR is not set at all"; fi
if [ -z "${VAR}" ];     then echo "MP:2 VAR is not set at all"; fi
)

出力は次のようになります。

JL:1 VARは全く設定されていない
MP:1 VARは全く設定されていない
MP:2 VARは全く設定されていない

2 番目のテストのペアでは、変数は設定されますが、空の値に設定されています。これは、${VAR=value}${VAR:=value}表記法によって区別されます。および${VAR-value}${VAR:-value}および${VAR+value}${VAR:+value}およびなどについても同様です。


としてギリ彼は指摘する答え、オプションbashを指定して実行するとset -o nounset、上記の基本的な回答は で失敗しますunbound variable。これは簡単に解決できます。

if [ -z "${VAR+xxx}" ]; then echo "VAR is not set at all"; fi
if [ -z "${VAR-}" ] && [ "${VAR+xxx}" = "xxx" ]; then echo "VAR is set but empty"; fi

または、 (と同等)set -o nounsetを使用してオプションをキャンセルすることもできます。set +uset -uset -o nounset

おすすめ記事