if
ステートメントで変数の存在を確認する必要があります。以下の影響があるもの:
if [ -v $somevar ]
then
echo "Variable somevar exists!"
else
echo "Variable somevar does not exist!"
そして、それに最も近い質問は this で、実際には私の質問に答えていません。
最新のbash(バージョン4.2以降):
[[ -v name_of_var ]]
help test
から:
-v VAR、シェル変数VARが設定されている場合はTrue
existsの意味に依存します。
宣言されているが割り当てられていない変数は存在しますか?
空のリストが割り当てられている配列(またはハッシュ)変数は存在しますか?
現在割り当てられていない変数を指すnameref変数は存在しますか?
$-
、$#
、$1
変数を考慮しますか? (POSIXはしません)。
ボーンのようなシェルでは、標準的な方法は次のとおりです。
if [ -n "${var+set}" ]; then
echo '$var was set'
fi
これは、スカラー変数やその他のパラメーターに対して機能し、変数に値が割り当てられているかどうかを示します(空、自動的、環境、割り当て、read
、for
などから)。
typeset
またはdeclare
コマンドがあるシェルの場合、setであった変数として報告されませんdeclaredただし、assignedzsh
を除き。
配列をサポートするシェルの場合、yash
とzsh
を除き、要素がないとset配列変数として報告されません。 of indice 0が設定されています。
bash
(ksh93
もzsh
も除く)の場合、連想配列型の変数の場合、キー「0」の要素が設定されていない限り、setとしてレポートされません。
ksh93
およびbash
の場合、タイプnamerefの変数の場合、namerefによって参照される変数がそれ自体はsetと見なされます。
ksh
、zsh
およびbash
の場合、より優れたアプローチは次のとおりです。
if ((${#var[@]})); then
echo '$var (or the variable it references for namerefs) or any of its elements for array/hashes has been set'
fi
ksh93
、zsh
、およびbash
4.4以降の場合、次のものもあります。
if typeset -p var 2> /dev/null | grep -q '^'; then
echo '$var exists'
fi
設定または宣言された変数を報告します。
[〜#〜] so [〜#〜] の回答で述べたように、次の方法で確認できます。
if [ -z ${somevar+x} ]; then echo "somevar is unset"; else echo "somevar is set to '$somevar'"; fi
ここで、$ {somevar + x}は、varが設定されていない場合はnullと評価され、それ以外の場合は文字列 "x"に置き換えられるパラメーター展開です。
他の回答で提案されているように-n
を使用すると、変数に空の文字列が含まれているかどうかのみがチェックされます。それはその存在をチェックしません。
POSIXly:
! (: "${somevar?}") 2>/dev/null && echo somevar unset
または、シェルにメッセージを表示させることもできます。
(: "${somevar?}")
zsh: somevar: parameter not set
if set|grep '^somevar=' >/dev/null;then
echo "somevar exists"
else
echo "does not exist"
fi
printf ${var+'$var exists!\n'}
...印刷しない場合は何も印刷しません。または...
printf $"var does%${var+.}s exist%c\n" \ not !
...どちらかの方法で教えてくれます。
テストの戻り値を使用して、条件に適したフォーマット文字列に動的に展開できます。
[ "${var+1}" ]
printf $"var does%.$?0s exist%c\n" \ not !
置換に基づいてprintf
を失敗させることもできます...
printf $"var does%${var+.}s exist%c\n%.${var+b}d" \
\ not ! \\c >&"$((2${var+-1}))" 2>/dev/null
...これは$var does not exist!
をstderrに送信し、$var
は設定されていませんが、出力$var does exist!
を標準出力に追加し、$var
が設定されています。
この単純な行は機能します(そしてほとんどのPOSIXシェルで機能します)。
${var+"false"} && echo "var is unset"
または、長い形式で記述します。
unset var
if ${var+"false"}
then
echo "var is unset"
fi
拡張は次のとおりです。
${var+"false"}
展開は、「null」または「false」のいずれかに展開されます。
次に、「nothing」または「false」が実行され、終了コードが設定されます。
コマンドtest
([
または[[
)は、拡張自体(の実行)によって終了値が設定されるためです。
bashscalarおよびarrayタイプの両方で機能する関数:
has_declare() { # check if variable is set at all
local "$@" # inject 'name' argument in local scope
&>/dev/null declare -p "$name" # return 0 when var is present
}
if has_declare name="vars_name" ; then
echo "variable present: vars_name=$vars_name"
fi
純粋なシェルの方法:
[ "${var+1}" ] || echo "The variable has not been set"
テストスクリプト:
#!/bin/sh
echo "Test 1, var has not yet been created"
[ "${var+1}" ] || echo "The variable has not been set"
echo "Test 2, var=1"
var=1
[ "${var+1}" ] || echo "The variable has not been set"
echo "Test 3, var="
var=
[ "${var+1}" ] || echo "The variable has not been set"
echo "Test 4, unset var"
unset var
[ "${var+1}" ] || echo "The variable has not been set"
echo "Done"
結果:
Test 1, var has not yet been created
The variable has not been set
Test 2, var=1
Test 3, var=
Test 4, unset var
The variable has not been set
Done
Bash 4.4.19では、以下がうまくいきました。ここに完全な例があります
$export MAGENTO_DB_Host="anyvalue"
#!/bin/bash
if [ -z "$MAGENTO_DB_Host" ]; then
echo "Magento variable not set"
else
echo $MAGENTO_DB_Host
fi
$array=()
@ Gillesの answer に加えて
_case " ${!foobar*} " in *" foobar "*) echo "foobar is declared";; *) echo "foobar is not declared";; esac
_
-関数内にカプセル化する方法が見つかりませんでした-部分的に Richard Hansen に基づいた単純なバージョンを追加したいと思います answer ですが、空のarray=()
で発生する落とし穴にも対処します。
_# The first parameter needs to be the name of the variable to be checked.
# (See example below)
var_is_declared() {
{ [[ -n ${!1+anything} ]] || declare -p $1 &>/dev/null;}
}
var_is_unset() {
{ [[ -z ${!1+anything} ]] && ! declare -p $1 &>/dev/null;}
}
_
$1
_に空の$array=()
の名前が含まれている場合、宣言を呼び出すと、正しい結果が得られます
次のコードで関数をテストできます:
_( # start a subshell to encapsulate functions/vars for easy copy-paste into the terminal
# do not use this extra parenthesis () in a script!
var_is_declared() {
{ [[ -n ${!1+anything} ]] || declare -p $1 &>/dev/null;}
}
var_is_unset() {
{ [[ -z ${!1+anything} ]] && ! declare -p $1 &>/dev/null;}
}
:; echo -n 'a; '; var_is_declared a && echo "# is declared" || echo "# is not declared"
a=; echo -n 'a=; '; var_is_declared a && echo "# is declared" || echo "# is not declared"
a="sd"; echo -n 'a="sd"; '; var_is_declared a && echo "# is declared" || echo "# is not declared"
a=(); echo -n 'a=(); '; var_is_declared a && echo "# is declared" || echo "# is not declared"
a=(""); echo -n 'a=(""); '; var_is_declared a && echo "# is declared" || echo "# is not declared"
unset a; echo -n 'unset a; '; var_is_declared a && echo "# is declared" || echo "# is not declared"
echo ;
:; echo -n 'a; '; var_is_unset a && echo "# is unset" || echo "# is not unset"
a=; echo -n 'a=; '; var_is_unset a && echo "# is unset" || echo "# is not unset"
a="foo"; echo -n 'a="foo"; '; var_is_unset a && echo "# is unset" || echo "# is not unset"
a=(); echo -n 'a=(); '; var_is_unset a && echo "# is unset" || echo "# is not unset"
a=(""); echo -n 'a=(""); '; var_is_unset a && echo "# is unset" || echo "# is not unset"
unset a; echo -n 'unset a; '; var_is_unset a && echo "# is unset" || echo "# is not unset"
)
_
スクリプトは戻るはずです
_a; # is not declared
a=; # is declared
a="foo"; # is declared
a=(); # is declared
a=(""); # is declared
unset a; # is not declared
a; # is unset
a=; # is not unset
a="foo"; # is not unset
a=(); # is not unset
a=(""); # is not unset
unset a; # is unset
_
if
コマンドを使用してbashで宣言された変数の存在を確認することはできませんが、新しいbashには-v
オプションが存在しますが、移植性がなく、古いbash
バージョン。なぜなら、存在しない変数を使用しているとき、それは同時に生まれるからです。
例えば。 MYTEST
変数に値を使用したり割り当てたりしなかったとしますが、echoコマンドを使用すると何も表示されません。または、if [ -z $MYTEST ]
を使用している場合、ゼロの値が返されました。この変数が存在しないことを示す別の終了ステータスは返されませんでした!
これで2つの解決策があります(-v
オプションなし):
declare
コマンドを使用します。set
コマンドを使用します。例えば:
MYTEST=2
set | grep MYTEST
declare | grep MYTEST
しかし、残念ながら、これらのコマンドはメモリに関数をロードしたことも示しています!よりきれいな結果を得るには、declare -p | grep -q MYTEST ; echo $?
コマンドを使用できます。