null文字列をチェックしたい場合は、
[ -z $mystr ]
しかし、変数が定義されているかどうかを確認したい場合はどうすればよいですか?または、Bashスクリプトに違いはありませんか?
簡単に説明されているわけではありませんが、あなたが求めている答えは、 Vinkoの答えによって暗示されていると思います(明記されていない場合)。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と組み合わせた個別の簡単なテストを使用することをお勧めし&&ます。問題のあるシステムに遭遇したことはありません。それは彼らがかつて存在していなかったことを意味するわけではありません(しかし、彼らが遠い過去にそれほど珍しくなかったとしても、それらはおそらく最近非常にまれです)。
これらの詳細、およびその他の関連するシェルパラメータの展開、testor[コマンド、および条件式は、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:1VARがまったく設定されていません MP:1VARがまったく設定されていない MP:2VARがまったく設定されていません
2番目のテストのペアでは、変数が設定されていますが、空の値に設定されています。${VAR=value}これは、と${VAR:=value}表記法の違いです。と、、${VAR-value}と${VAR:-value}、など${VAR+value}も${VAR:+value}同様です。
Giliが彼の答えで指摘しているよう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
~> if [ -z $FOO ]; then echo "EMPTY"; fi
EMPTY
~> FOO=""
~> if [ -z $FOO ]; then echo "EMPTY"; fi
EMPTY
~> FOO="a"
~> if [ -z $FOO ]; then echo "EMPTY"; fi
~>
-zは未定義の変数に対しても機能します。未定義と定義済みを区別するには、ここにリストされているものを使用するか、より明確な説明とともに、ここにリストされているものを使用します。
最もクリーンな方法は、これらの例のように拡張を使用することです。すべてのオプションを取得するには、マニュアルの「パラメータ拡張」セクションを確認してください。
代替語:
~$ unset FOO
~$ if test ${FOO+defined}; then echo "DEFINED"; fi
~$ FOO=""
~$ if test ${FOO+defined}; then echo "DEFINED"; fi
DEFINED
デフォルト値:
~$ FOO=""
~$ if test "${FOO-default value}" ; then echo "UNDEFINED"; fi
~$ unset FOO
~$ if test "${FOO-default value}" ; then echo "UNDEFINED"; fi
UNDEFINED
もちろん、これらのいずれかを別の方法で使用し、「デフォルト値」の代わりに必要な値を設定し、必要に応じて拡張を直接使用します。
高度な bash スクリプト ガイド、10.2。パラメータ置換:
変数 $mystr が定義されているかどうかに基づいてプログラム ロジックを作成するには、次のようにします。
isdefined=0
${mystr+ export isdefined=1}
現在、isdefined=0 の場合、変数は未定義であり、isdefined=1 の場合、変数は定義済みです
変数をチェックするこの方法は、よりエレガントで読みやすいため、上記の回答よりも優れています。未定義の変数の使用でエラーが発生するように bash シェルが構成されている場合(set -u)、スクリプトは途中で終了します。
その他の便利なもの:
$mystr が未定義の場合はデフォルト値の 7 を割り当て、それ以外の場合はそのままにします。
mystr=${mystr- 7}
変数が未定義の場合、エラー メッセージを出力して関数を終了します。
: ${mystr? not defined}
$mystr の内容が定義されている場合にコマンドとして実行されないように、':' を使用していることに注意してください。
テストの要約。
[ -n "$var" ] && echo "var is set and not empty"
[ -z "$var" ] && echo "var is unset or empty"
[ "${var+x}" = "x" ] && echo "var is set" # may or may not be empty
[ -n "${var+x}" ] && echo "var is set" # may or may not be empty
[ -z "${var+x}" ] && echo "var is unset"
[ -z "${var-x}" ] && echo "var is set and empty"
https://stackoverflow.com/a/9824943/14731には、より良い回答 (より読みやすく、set -o nounset有効にすると機能するもの) が含まれています。おおよそ次のように機能します。
if [ -n "${VAR-}" ]; then
echo "VAR is set and is not empty"
elif [ "${VAR+DEFINED_BUT_EMPTY}" = "DEFINED_BUT_EMPTY" ]; then
echo "VAR is set, but empty"
else
echo "VAR is not set"
fi
別のオプション:「配列インデックスのリスト」展開:
$ unset foo
$ foo=
$ echo ${!foo[*]}
0
$ foo=bar
$ echo ${!foo[*]}
0
$ foo=(bar baz)
$ echo ${!foo[*]}
0 1
これが空の文字列に展開されるのは、fooが設定されていないときだけなので、条件付きの文字列で確認できます。
$ unset foo
$ [[ ${!foo[*]} ]]; echo $?
1
$ foo=
$ [[ ${!foo[*]} ]]; echo $?
0
$ foo=bar
$ [[ ${!foo[*]} ]]; echo $?
0
$ foo=(bar baz)
$ [[ ${!foo[*]} ]]; echo $?
0
3.0以上のbashバージョンで利用可能である必要があります
このバイクをさらに流さないで、追加したかった
shopt -s -o nounset
これは、スクリプトの先頭に追加できるものであり、変数がスクリプトのどこにも宣言されていない場合はエラーになります。表示されるメッセージはですunbound variableが、他の人が言及しているように、空の文字列やnull値をキャッチしません。個々の値が空でないことを確認するために、変数がで展開されるときに変数をテストできます。${mystr:?}これはドル記号展開とも呼ばれ、でエラーが発生しparameter null or not setます。
変数が定義されているかどうかを確認するためのより明確な方法は次のとおりです。
var_defined() {
local var_name=$1
set | grep "^${var_name}=" 1>/dev/null
return $?
}
次のように使用します。
if var_defined foo; then
echo "foo is defined"
else
echo "foo is not defined"
fi
引数なしでsetを呼び出します。定義されたすべての変数を出力します。
リストの最後の変数はスクリプトで定義されたものになります。
そのため、定義されているものと定義されていないものを把握できるものに出力をパイプできます。