変数がBashで設定されているかどうかを確認するにはどうすればよいですか?
たとえば、ユーザーが関数に最初のパラメーターを指定したかどうかを確認するにはどうすればよいですか?
function a {
# if $1 is set ?
}
-v
テストに問題はbash
ありませんが、これは新しいバージョンのでのみ利用可能で、シェル間での移植性はないようです。
変数がBashで設定されているかどうかを確認するにはどうすればよいですか?
たとえば、ユーザーが関数に最初のパラメーターを指定したかどうかを確認するにはどうすればよいですか?
function a {
# if $1 is set ?
}
-v
テストに問題はbash
ありませんが、これは新しいバージョンのでのみ利用可能で、シェル間での移植性はないようです。
回答:
if [ -z ${var+x} ]; then echo "var is unset"; else echo "var is set to '$var'"; fi
どこに${var+x}
あるパラメータ展開ならば何にも評価されvar
設定されていない、との文字列を置換しx
そう。
この構文と使用法は、引用符を必要としないものにのみ展開されるため、引用符は省略できます(そのため、${var+x}
代わりにと言います)。何もありません(結果として、便利に同じ値(true)に評価されます)))。"${var+x}"
x
[ -z ]
[ -z "" ]
ただし、引用符は安全に省略でき、すぐには明らかではありませんでしたが(主要なBashコーダーでもあるこの引用符の説明の筆頭著者にも明らかではありませんでした)、ソリューションを記述する方が良い場合があります引用符付き[ -z "${var+x}" ]
O(1)速度のペナルティの非常に小さい可能なコストで、。最初の著者も、このソリューションを使用してコードの横にコメントとしてこれを追加し、この回答へのURLを提供しています。これには、引用符を安全に省略できる理由の説明も含まれています。
if [ -z "$var" ]; then echo "var is blank"; else echo "var is set to '$var'"; fi
設定されていない変数と空の文字列に設定されている変数を区別しないため、これはしばしば間違っています。つまり、var=''
、上記のソリューションは「var is blank」を出力します。
unsetと "set to the empty string"の区別は、ユーザーが拡張子またはプロパティの追加リストを指定する必要があり、それらを指定しないとデフォルトで空でない値になり、空の文字列を指定する必要がある場合に不可欠です。スクリプトが空の拡張子または追加のプロパティのリストを使用するようにします。
ただし、区別はすべてのシナリオで必須ではありません。これらの場合 [ -z "$var" ]
は問題ありません。
${var+x}
使用する正しい置換です。を使用[ -z ${var:+x} ]
してもと同じ結果が得られ[ -z "$var" ]
ます。
[ -z "" -a -z ${var+x} ]
取得bash: [: argument expected
します。たまに機能する構文を使用した答えは本当に嫌いです。
[ -z $var ]
は、引用符を省略することと同じです。いずれにせよ、あなたはあなたの入力について仮定をしている。空の文字列を未設定として扱う場合は、これで十分[ -z $var ]
です。
非ヌル/非ゼロ文字列変数を確認するには、つまり設定されている場合は、次を使用します。
if [ -n "$1" ]
の逆です-z
。私はを-n
超えて使用しています-z
。
次のように使用します。
if [ -n "$1" ]; then
echo "You supplied the first parameter!"
else
echo "First parameter not supplied."
fi
[]
特にシェル(非bash)スクリプトでよりよく機能します。
set -u
。
ここではどのようにテストにだパラメータがあるかどうかを設定しない、または空(「ヌル」)または値のセット:
+--------------------+----------------------+-----------------+-----------------+
| Expression | parameter | parameter | parameter |
| in script: | Set and Not Null | Set But Null | Unset |
+--------------------+----------------------+-----------------+-----------------+
| ${parameter:-word} | substitute parameter | substitute word | substitute word |
| ${parameter-word} | substitute parameter | substitute null | substitute word |
| ${parameter:=word} | substitute parameter | assign word | assign word |
| ${parameter=word} | substitute parameter | substitute null | assign word |
| ${parameter:?word} | substitute parameter | error, exit | error, exit |
| ${parameter?word} | substitute parameter | substitute null | error, exit |
| ${parameter:+word} | substitute word | substitute null | substitute null |
| ${parameter+word} | substitute word | substitute word | substitute null |
+--------------------+----------------------+-----------------+-----------------+
「substitute」で示されているすべてのケースで、式は示されている値で置き換えられます。「assign」で示されるすべてのケースで、パラメーターにはその値が割り当てられ、式も置き換えられます。
これを実際に表示するには:
+--------------------+----------------------+-----------------+-----------------+
| Expression | FOO="world" | FOO="" | unset FOO |
| in script: | (Set and Not Null) | (Set But Null) | (Unset) |
+--------------------+----------------------+-----------------+-----------------+
| ${FOO:-hello} | world | hello | hello |
| ${FOO-hello} | world | "" | hello |
| ${FOO:=hello} | world | FOO=hello | FOO=hello |
| ${FOO=hello} | world | "" | FOO=hello |
| ${FOO:?hello} | world | error, exit | error, exit |
| ${FOO?hello} | world | "" | error, exit |
| ${FOO:+hello} | hello | "" | "" |
| ${FOO+hello} | hello | hello | "" |
+--------------------+----------------------+-----------------+-----------------+
set foo; echo ${1:-set but null or unset}
ます。「foo」をエコーします。set --; echo ${1:-set but null or unset}
エコーが設定されていますがnull ...
set
:-)で設定できます
: ${FOOBAR:=/etc/foobar.conf}
は、変数が設定されていないかnullの場合、変数のデフォルト値を設定することです。
parameter
変数名です。 word
使用しているテーブルの構文、および変数$parameter
が設定されているか、設定されているがnullであるか、設定されていないかに応じて、置換する文字列です。複雑にするためでword
はなく、変数を含めることもできます!これは、文字で区切られたオプションの引数を渡すのに非常に役立ちます。例: 設定されているがnullではない場合${parameter:+,${parameter}}
、コンマ区切りで出力し,$parameter
ます。この場合、word
ある,${parameter}
ここで述べられているテクニックのほとんどは正しいですが、bash 4.2は変数の値をテストするのではなく、変数の存在の実際のテスト(man bash)をサポートしています。
[[ -v foo ]]; echo $?
# 1
foo=bar
[[ -v foo ]]; echo $?
# 0
foo=""
[[ -v foo ]]; echo $?
# 0
特に、set -u
/ set -o nounset
などの多くのアプローチとは異なり、/ モードで設定されていない変数を確認するためにこのアプローチを使用しても、エラーは発生しません[ -z
。
[[ -v aaa ]]; echo $?
==>-bash: conditional binary operator expected
-bash: syntax error near 'aaa'
declare -a foo
これを行うには多くの方法があり、次のものがその1つです。
if [ -z "$1" ]
$ 1がnullまたは未設定の場合、これは成功します
[[ ]]
移植性の落とし穴にすぎません。if [ -n "$1" ]
ここで使用する必要があります。
foo=""
、$foo
値を持っていますが、-z
単にそれが空だことを報告します。そして、-z $foo
あなたが持っている場合は爆破されますset -o nounset
。
foo=
)かどうかを確認したい場合、ラッセルの答えは正しいです。
私はいつも他の答えでPOSIXテーブルを見つけるのが遅いので、ここでそれを私の見解とします:
+----------------------+------------+-----------------------+-----------------------+
| if VARIABLE is: | set | empty | unset |
+----------------------+------------+-----------------------+-----------------------+
- | ${VARIABLE-default} | $VARIABLE | "" | "default" |
= | ${VARIABLE=default} | $VARIABLE | "" | $(VARIABLE="default") |
? | ${VARIABLE?default} | $VARIABLE | "" | exit 127 |
+ | ${VARIABLE+default} | "default" | "default" | "" |
+----------------------+------------+-----------------------+-----------------------+
:- | ${VARIABLE:-default} | $VARIABLE | "default" | "default" |
:= | ${VARIABLE:=default} | $VARIABLE | $(VARIABLE="default") | $(VARIABLE="default") |
:? | ${VARIABLE:?default} | $VARIABLE | exit 127 | exit 127 |
:+ | ${VARIABLE:+default} | "default" | "" | "" |
+----------------------+------------+-----------------------+-----------------------+
各グループ(前のコロンがある場合とない場合)のセットとセット解除のケースは同じであるため、唯一の違いは空の方法です。ケースの処理方法です。
前のコロンでは、空のケースと未設定のケースは同じなので、可能な場合は使用します(つまり:=
、=
な場合は、空のケースに一貫性がないため、で)。
見出し:
VARIABLE
は空ではない(VARIABLE="something"
)VARIABLE
(空/ヌルですVARIABLE=""
)であるVARIABLE
存在しないことを意味します(unset VARIABLE
)値:
$VARIABLE
結果は変数の元の値であることを意味します。"default"
結果は提供された置換文字列でした。""
結果がnull(空の文字列)であることを意味します。exit 127
スクリプトが終了コード127で実行を停止することを意味します。$(VARIABLE="default")
結果は変数の元の値であることを意味し、将来の使用のための変数に割り当てられて設けられた置換文字列。VARIABLE=""
と書くことができますVARIABLE=
。それでも、前者の方が読みやすいです。
変数が空でないかどうかを確認するには、
if [[ $var ]]; then ... # `$var' expands to a nonempty string
逆の場合は、変数が設定されていないか空であるかをテストします。
if [[ ! $var ]]; then ... # `$var' expands to the empty string (set or not)
変数が設定されているかどうか(空か空でないか)を確認するには、
if [[ ${var+x} ]]; then ... # `var' exists (empty or nonempty)
if [[ ${1+x} ]]; then ... # Parameter 1 exists (empty or nonempty)
逆の場合、変数が設定されていないかどうかをテストします。
if [[ ! ${var+x} ]]; then ... # `var' is not set at all
if [[ ! ${1+x} ]]; then ... # We were called with no arguments
${variable+x}
を取得するx
場合に限っては$variable
ほぼ半分前年に設定されています)。また、なぜそれが正しいのかを説明する詳細な説明もあります。
${variable+x}
読み
最近のバージョンのBash(4.2以降かと思います。よくわかりません)では、次のようにします。
if [ ! -v SOMEVARIABLE ] #note the lack of a $ sigil
then
echo "Variable is unset"
elif [ -z "$SOMEVARIABLE" ]
then
echo "Variable is set to an empty string"
else
echo "Variable is set to some string"
fi
[ -v "$VARNAME" ]
、これは誤りではなく、単に別のテストを実行することに注意してください。と仮定しVARNAME=foo
ます。次に、という名前の変数foo
が設定されているかどうかを確認します。
-v
POSIXに準拠していません
[: -v: unexpected operator
、のbash
代わりに使用することを確認する必要がありsh
ます。
if [ "$1" != "" ]; then
echo \$1 is set
else
echo \$1 is not set
fi
引数については、私の意見では通常、引数の数である$#をテストするのが最善です。
if [ $# -gt 0 ]; then
echo \$1 is set
else
echo \$1 is not set
fi
[ "$1" != "" ]
(または[ -n "$1" ]
)...
$1
が空の文字列に設定されている場合、これは失敗します。
$1
、空の文字列に設定されている場合に、回答の最初の部分が機能しない場合に役立つ回避策です。
set -o nounset
がオンの場合、これは失敗します。
bash
タグがあるので、バッシュに重点を置いた答えを出しています。
Bashで名前付き変数のみを処理している限り、この関数は、たとえそれが空の配列であっても、変数が設定されているかどうかを常に通知するはずです。
variable-is-set() {
declare -p "$1" &>/dev/null
}
Bash(少なくとも3.0まで)では、var
が宣言/設定された変数であるdeclare -p var
場合、declare
変数var
を現在のタイプと値に設定し、ステータスコード0
(成功)を返すコマンドを出力します。var
が宣言されていない場合はdeclare -p var
、にエラーメッセージを出力し、stderr
ステータスコードを返します1
。を使用して&>/dev/null
、通常stdout
とstderr
出力の両方を/dev/null
、表示されることはなく、ステータスコードは変更されません。したがって、関数はステータスコードのみを返します。
[ -n "$var" ]
:これは、${var[0]}
が空でないかどうかのみをチェックします。(Bashでは$var
、と同じ${var[0]}
です。)[ -n "${var+x}" ]
:これは、${var[0]}
が設定されているかどうかのみをチェックします。[ "${#var[@]}" != 0 ]
:これは、少なくとも1つのインデックス$var
が設定されているかどうかをチェックするだけです。
これは(を含むという名前の変数のために働く$_
)、いない特定の特殊変数($!
、$@
、$#
、$$
、$*
、$?
、$-
、$0
、$1
、$2
、...、および任意の私が忘れてしまっている場合があります)。これらはいずれも配列ではないため、POSIXスタイル[ -n "${var+x}" ]
はこれらの特殊変数のすべてに対して機能します。ただし、関数が呼び出されると、多くの特殊変数が値/存在を変更するため、関数でのラップには注意してください。
スクリプトに配列があり、できるだけ多くのシェルと互換性を持たせる場合は、typeset -p
ではなくを使用することを検討してくださいdeclare -p
。kshは前者のみをサポートすることを読みましたが、これをテストすることはできませんでした。Bash 3.0+とZsh 5.5.1はどちらもとの両方typeset -p
をサポートしていることは知っていdeclare -p
ます。ただし、これら2つのキーワード以外の違いについてはテストしていません。また、他のシェルについてもテストしていません。
スクリプトをPOSIX sh互換にする必要がある場合は、配列を使用できません。配列なしで[ -n "{$var+x}" ]
動作します。
この関数はvar
、variableの設定を解除しeval
、渡されたコードをsし、テストを実行var
して、eval
dコードによって設定されているかどうかを判断し、最終的に、さまざまなテストの結果のステータスコードを表示します。
私はスキップだtest -v var
、[ -v var ]
と[[ -v var ]]
彼らはPOSIX標準に同じ結果が得られるので[ -n "${var+x}" ]
、バッシュ4.2 +を必要としています。私がテストしたシェル(Bash 3.0から5.0、およびZsh 5.5.1)とtypeset -p
同じなのでスキップしdeclare -p
ます。
is-var-set-after() {
# Set var by passed expression.
unset var
eval "$1"
# Run the tests, in increasing order of accuracy.
[ -n "$var" ] # (index 0 of) var is nonempty
nonempty=$?
[ -n "${var+x}" ] # (index 0 of) var is set, maybe empty
plus=$?
[ "${#var[@]}" != 0 ] # var has at least one index set, maybe empty
count=$?
declare -p var &>/dev/null # var has been declared (any type)
declared=$?
# Show test results.
printf '%30s: %2s %2s %2s %2s\n' "$1" $nonempty $plus $count $declared
}
変数が連想配列として宣言されていない場合、Bashは非数値配列インデックスを「0」として扱うため、テスト結果は予期しないものになる可能性があることに注意してください。また、連想配列はBash 4.0以降でのみ有効です。
# Header.
printf '%30s: %2s %2s %2s %2s\n' "test" '-n' '+x' '#@' '-p'
# First 5 tests: Equivalent to setting 'var=foo' because index 0 of an
# indexed array is also the nonindexed value, and non-numerical
# indices in an array not declared as associative are the same as
# index 0.
is-var-set-after "var=foo" # 0 0 0 0
is-var-set-after "var=(foo)" # 0 0 0 0
is-var-set-after "var=([0]=foo)" # 0 0 0 0
is-var-set-after "var=([x]=foo)" # 0 0 0 0
is-var-set-after "var=([y]=bar [x]=foo)" # 0 0 0 0
# '[ -n "$var" ]' fails when var is empty.
is-var-set-after "var=''" # 1 0 0 0
is-var-set-after "var=([0]='')" # 1 0 0 0
# Indices other than 0 are not detected by '[ -n "$var" ]' or by
# '[ -n "${var+x}" ]'.
is-var-set-after "var=([1]='')" # 1 1 0 0
is-var-set-after "var=([1]=foo)" # 1 1 0 0
is-var-set-after "declare -A var; var=([x]=foo)" # 1 1 0 0
# Empty arrays are only detected by 'declare -p'.
is-var-set-after "var=()" # 1 1 1 0
is-var-set-after "declare -a var" # 1 1 1 0
is-var-set-after "declare -A var" # 1 1 1 0
# If 'var' is unset, then it even fails the 'declare -p var' test.
is-var-set-after "unset var" # 1 1 1 1
ヘッダ行対応のテストニーモニックに[ -n "$var" ]
、[ -n "${var+x}" ]
、[ "${#var[@]}" != 0 ]
、およびdeclare -p var
、それぞれ。
test: -n +x #@ -p
var=foo: 0 0 0 0
var=(foo): 0 0 0 0
var=([0]=foo): 0 0 0 0
var=([x]=foo): 0 0 0 0
var=([y]=bar [x]=foo): 0 0 0 0
var='': 1 0 0 0
var=([0]=''): 1 0 0 0
var=([1]=''): 1 1 0 0
var=([1]=foo): 1 1 0 0
declare -A var; var=([x]=foo): 1 1 0 0
var=(): 1 1 1 0
declare -a var: 1 1 1 0
declare -A var: 1 1 1 0
unset var: 1 1 1 1
declare -p var &>/dev/null
(100%?)3.0以降のBashで名前付き変数をテストするための信頼性があります。[ -n "${var+x}" ]
POSIX準拠の状況では信頼できますが、配列を処理できません。- 変数が空でないかどうかをチェックするため、および他のシェルで宣言された変数をチェックするための他のテストが存在します。ただし、これらのテストは、BashスクリプトとPOSIXスクリプトのどちらにも適していません。
declare -p var &>/dev/null
)が機能する唯一のものです。ありがとうございました!
... &> /dev/null
が、SOは単一の文字の編集を許可しなかった🙄(> 6文字でなければならない-空白を追加しようとしてもしかし、それはうまくいきませんでした)。また、あなたが指摘したように、などの特別な変数はここでは機能しないので$1
、サンプルの名前付き変数(たとえばOUTPUT_DIR
)に切り替えるように関数を変更する価値があるかもしれ$1
ません。とにかく、それは重要な編集です。それ以外の場合、コードはnull
という相対ディレクトリにというファイルを作成しようとしていますdev
。ところで-素晴らしい答えです!
declare -p PATH &> /dev/null
ます。0をdeclare -p ASDFASDGFASKDF &> /dev/null
返し、as は1 を返します(bash 5.0.11(1)-releaseの場合)
declare var
変数を変数として宣言しますが、次のように設定しませんset -o nounset
:declare foo bar=; set -o nounset; echo $bar; echo $foo
/
!私はそれを修正しましたが、特に@xebecheのコメントに照らして、ロジックは機能を保証するのに十分に混乱していると思います。@xebecheこれは私の答えには不便です。… declare -p "$1" | grep =
またはのようなものを試さなければならないようtest -v "$1"
です。
スクリプトで次のように設定されている場合に、 未設定または空かどうかを確認しようとしている人のためにset -u
:
if [ -z "${var-}" ]; then
echo "Must provide var environment variable. Exiting...."
exit 1
fi
定期的な[ -z "$var" ]
チェックはして失敗するvar; unbound variable
場合set -u
が、[ -z "${var-}" ]
拡大する場合は、空の文字列にvar
失敗することなく設定されていません。
${var:-}
であるべきではありません${var-}
。しかし、Bashでは、コロンがなくても機能することを確認できます。
${var:-}
そして、${var-}
異なるものを意味します。${var:-}
場合は、空の文字列に展開されますvar
未設定またはヌルと${var-}
のみ未設定の場合、文字列を空に拡大していきます。
これでうまくいきました。パラメータが設定されていない場合、スクリプトにエラーメッセージを表示して終了させたいと思いました。
#!/usr/bin/env bash
set -o errexit
# Get the value and empty validation check all in one
VER="${1:?You must pass a version of the format 0.0.0 as the only argument}"
実行するとエラーが返されます
peek@peek:~$ ./setver.sh
./setver.sh: line 13: 1: You must pass a version of the format 0.0.0 as the only argument
値がset = VALIDまたはunset / empty = INVALIDかどうかを確認するだけの場合は、このオプションを試してください。
TSET="good val"
TEMPTY=""
unset TUNSET
if [ "${TSET:-}" ]; then echo "VALID"; else echo "INVALID";fi
# VALID
if [ "${TEMPTY:-}" ]; then echo "VALID"; else echo "INVALID";fi
# INVALID
if [ "${TUNSET:-}" ]; then echo "VALID"; else echo "INVALID";fi
# INVALID
または、短いテストでも;-)
[ "${TSET:-}" ] && echo "VALID" || echo "INVALID"
[ "${TEMPTY:-}" ] && echo "VALID" || echo "INVALID"
[ "${TUNSET:-}" ] && echo "VALID" || echo "INVALID"
そして、これが質問への答えです。値がset / empty = VALIDまたはunset = INVALIDかどうかを確認するだけの場合は、これを使用します。
注、「..- 1}」の「1」は重要ではなく、何でもかまいません(xなど)
TSET="good val"
TEMPTY=""
unset TUNSET
if [ "${TSET+1}" ]; then echo "VALID"; else echo "INVALID";fi
# VALID
if [ "${TEMPTY+1}" ]; then echo "VALID"; else echo "INVALID";fi
# VALID
if [ "${TUNSET+1}" ]; then echo "VALID"; else echo "INVALID";fi
# INVALID
短いテスト
[ "${TSET+1}" ] && echo "VALID" || echo "INVALID"
[ "${TEMPTY+1}" ] && echo "VALID" || echo "INVALID"
[ "${TUNSET+1}" ] && echo "VALID" || echo "INVALID"
この回答は、質問に正確に回答するように要求した@ mklement0(コメント)に捧げます。
リファレンスhttp://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02
変数に空でない値が設定されているかどうかを確認するに[ -n "$x" ]
は、他のユーザーがすでに示しているように、を使用します。
ほとんどの場合、値が空の変数は、設定されていない変数と同じように扱うことをお勧めします。:あなたがする必要がある場合しかし、あなたは2を区別することができます[ -n "${x+set}" ]
("${x+set}"
に展開されset
ている場合x
場合は、空の文字列に設定され、にx
設定されていません)。
パラメータが渡されたかどうかを確認するには$#
、関数(または関数ではない場合はスクリプト)に渡されるパラメータの数をテストします(Paulの回答を参照)。
bash
マニュアルページの「パラメータ拡張」セクションを読んでください。パラメーターの展開では、設定される変数の一般的なテストは行われませんが、パラメーターが設定されていない場合、パラメーターに対して実行できることがいくつかあります。
例えば:
function a {
first_arg=${1-foo}
# rest of the function
}
割り当てられfirst_arg
ている$1
場合はに設定され、それ以外の場合は値「foo」が使用されます。場合はa
、絶対に、単一のパラメータを取り、何も良いデフォルトが存在してはならないパラメータが与えられていないとき、あなたはエラーメッセージを出して終了することができます:
function a {
: ${1?a must take a single argument}
# rest of the function
}
(:
引数の値を展開するだけのnullコマンドとしての使用に注意してください。$1
この例では何もしたくないので、設定されていない場合は終了します)
: ${var?message}
ます。
を使用すること[[ -z "$var" ]]
は、変数が設定されているかどうかを確認する最も簡単な方法ですが、そのオプション-z
は、未設定の変数と空の文字列に設定された変数を区別しません。
$ set=''
$ [[ -z "$set" ]] && echo "Set" || echo "Unset"
Unset
$ [[ -z "$unset" ]] && echo "Set" || echo "Unset"
Unset
変数のタイプ(env変数、パラメーター、または通常の変数)に従ってチェックすることをお勧めします。
環境変数の場合:
[[ $(env | grep "varname=" | wc -l) -eq 1 ]] && echo "Set" || echo "Unset"
パラメータの場合(たとえば、パラメータの存在を確認するには$5
):
[[ $# -ge 5 ]] && echo "Set" || echo "Unset"
通常の変数の場合(補助関数を使用して、エレガントな方法で実行するには):
function declare_var {
declare -p "$1" &> /dev/null
}
declare_var "var_name" && echo "Set" || echo "Unset"
ノート:
$#
:位置パラメータの数を示します。declare -p
:パラメータとして渡される変数の定義を提供します。存在する場合は0を返し、存在しない場合は1を返し、エラーメッセージを出力します。&> /dev/null
:declare -p
戻りコードに影響を与えずにからの出力を抑制します。
上記の回答set -u
は、Bashオプションが有効になっている場合は機能しません。また、それらは動的ではありません。たとえば、「ダミー」という名前の変数が定義されているかどうかをテストする方法は定義されていますか?これを試して:
is_var_defined()
{
if [ $# -ne 1 ]
then
echo "Expected exactly one argument: variable name as string, e.g., 'my_var'"
exit 1
fi
# Tricky. Since Bash option 'set -u' may be enabled, we cannot directly test if a variable
# is defined with this construct: [ ! -z "$var" ]. Instead, we must use default value
# substitution with this construct: [ ! -z "${var:-}" ]. Normally, a default value follows the
# operator ':-', but here we leave it blank for empty (null) string. Finally, we need to
# substitute the text from $1 as 'var'. This is not allowed directly in Bash with this
# construct: [ ! -z "${$1:-}" ]. We need to use indirection with eval operator.
# Example: $1="var"
# Expansion for eval operator: "[ ! -z \${$1:-} ]" -> "[ ! -z \${var:-} ]"
# Code execute: [ ! -z ${var:-} ]
eval "[ ! -z \${$1:-} ]"
return $? # Pedantic.
}
できるよ:
function a {
if [ ! -z "$1" ]; then
echo '$1 is set'
fi
}
-n
、否定しないでください-z
。
$1
つまり、引用符が必要です[ ! -z "$1" ]
。または[[ ! -z $1 ]]
、bash / ksh / zshに書き込むこともできます。
$1
が空の文字列に設定されている場合、これは失敗します。
私の好ましい方法はこれです:
$ var=10
$ if ! ${var+false};then echo "is set";else echo "NOT set";fi
is set
$ unset -v var
$ if ! ${var+false};then echo "is set";else echo "NOT set";fi
NOT set
したがって、基本的に、変数が設定されている場合、それは「結果の否定false
」になります(何がtrue
=「設定される」)。
また、設定されていない場合は、「結果の否定true
」になります(空の結果はに評価されるためtrue
)(つまり、false
「=設定されていません」として終了します)。
[[ $foo ]]
または
(( ${#foo} ))
または
let ${#foo}
または
declare -p foo
if [[ ${1:+isset} ]]
then echo "It was set and not null." >&2
else echo "It was not set or it was null." >&2
fi
if [[ ${1+isset} ]]
then echo "It was set but might be null." >&2
else echo "It was was not set." >&2
fi
で何かを確認したい場合は、これを行うための(はるかに)優れたコードを見つけました$@
。
if [[$ 1 = ""]] その後 エコー '$ 1 is blank' そうしないと エコー '$ 1がいっぱいです' fi
なぜこれがすべてなのか のすべて$@
がBash に存在しますが、デフォルトでは空白になっているためtest -z
、test -n
役に立ちませんでした。
更新:パラメータの文字数を数えることもできます。
[$ {#1} = 0の場合] その後 エコー '$ 1 is blank' そうしないと エコー '$ 1がいっぱいです' fi
これは私が毎日使うものです:
#
# Check if a variable is set
# param1 name of the variable
#
function is_set()
{
[[ -n "${1}" ]] && test -n "$(eval "echo "\${${1}+x}"")"
}
これは、bash 3.0までのLinuxおよびSolarisでうまく機能します。
bash-3.00$ myvar="TEST"
bash-3.00$ is_set myvar ; echo $?
0
bash-3.00$ mavar=""
bash-3.00$ is_set myvar ; echo $?
0
bash-3.00$ unset myvar
bash-3.00$ is_set myvar ; echo $?
1
私はbashの大まかな詳細を隠す補助関数が好きです。この場合、そうすることでさらに(隠された)粗さが追加されます。
# The first ! negates the result (can't use -n to achieve this)
# the second ! expands the content of varname (can't do ${$varname})
function IsDeclared_Tricky
{
local varname="$1"
! [ -z ${!varname+x} ]
}
私はこの実装に最初にバグがあったため(イェンスとライオネルの回答に触発されて)、別の解決策を考え出しました。
# Ask for the properties of the variable - fails if not declared
function IsDeclared()
{
declare -p $1 &>/dev/null
}
私はそれがより簡単で、よりずんぐりしていて、理解/覚えやすいと思う。テストケースはそれが同等であることを示しています:
function main()
{
declare -i xyz
local foo
local bar=
local baz=''
IsDeclared_Tricky xyz; echo "IsDeclared_Tricky xyz: $?"
IsDeclared_Tricky foo; echo "IsDeclared_Tricky foo: $?"
IsDeclared_Tricky bar; echo "IsDeclared_Tricky bar: $?"
IsDeclared_Tricky baz; echo "IsDeclared_Tricky baz: $?"
IsDeclared xyz; echo "IsDeclared xyz: $?"
IsDeclared foo; echo "IsDeclared foo: $?"
IsDeclared bar; echo "IsDeclared bar: $?"
IsDeclared baz; echo "IsDeclared baz: $?"
}
main
テストケースは、varを宣言local var
しないことも示しています(「=」が後に続かない限り)。かなり長い間、この方法で変数を宣言したと思っていましたが、今は自分の意図を単に表現しているだけであることに気づきました...それは何もしません。
IsDeclared_Tricky xyz:1
IsDeclared_Tricky foo:1
IsDeclared_Tricky bar:0
IsDeclared_Tricky baz:0
IsDeclared xyz:1
IsDeclared foo:1
IsDeclared bar:0
IsDeclared baz:0
ボーナス:ユースケース
私は主にこのテストを使用して、やや「優雅」で安全な方法で(ほとんどインターフェースに似ています...)関数にパラメーターを提供(および返す)します。
#auxiliary functions
function die()
{
echo "Error: $1"; exit 1
}
function assertVariableDeclared()
{
IsDeclared "$1" || die "variable not declared: $1"
}
function expectVariables()
{
while (( $# > 0 )); do
assertVariableDeclared $1; shift
done
}
# actual example
function exampleFunction()
{
expectVariables inputStr outputStr
outputStr="$inputStr world!"
}
function bonus()
{
local inputStr='Hello'
local outputStr= # remove this to trigger error
exampleFunction
echo $outputStr
}
bonus
すべてで呼び出された場合、宣言された変数が必要です。
こんにちは世界!
そうしないと:
エラー:変数が宣言されていません:outputStr
すべての答えをすくい取った後、これも機能します:
if [[ -z $SOME_VAR ]]; then read -p "Enter a value for SOME_VAR: " SOME_VAR; fi
echo "SOME_VAR=$SOME_VAR"
SOME_VAR
私が持っているものの代わりにあなたが入れなければ$SOME_VAR
、それはそれを空の値に設定します。$
これが機能するために必要です。
set -u
される場合は機能しませんunboud variable
test -n "${var-}"
変数が空でないかどうかを確認するために使用します(したがって、定義/設定も必要です)test ! -z "${var+}"
変数が定義または設定されているかどうかを確認するために使用します(空であっても)シェルスクリプトでは最初の使用例がはるかに一般的であり、これが通常使用するものです。
このソリューションがどのように機能するかを理解するには、POSIX test
コマンドとPOSIXシェルパラメータ展開(spec)を理解する必要があります。そのため、答えを理解するために必要な絶対的な基礎をカバーしましょう。
testコマンドは式を評価し、(終了ステータスを介して)trueまたはfalseを返します。-n
オペランドが空でない文字列の場合、演算子はtrueを返します。したがって、たとえば、test -n "a"
trueをtest -n ""
返し、false を返します。これで、変数が空ではない(つまり、定義する必要がある)かどうかを確認するには、を使用できますtest -n "$var"
。ただし、一部のシェルスクリプトにはオプションセット(set -u
)があり、未定義の変数を参照するとエラーが発生するため、変数var
が定義されていない場合、式$a
によってエラーが発生します。このケースを正しく処理するには、変数拡張を使用する必要があります。これにより、変数が定義されていない場合は変数を代替文字列に置き換えるようにシェルに指示し、前述のエラーを回避します。
変数の展開と${var-}
は、変数var
が定義されていない場合(「unset」とも呼ばれる)、空の文字列に置き換えることです。したがって、test -n "${var-}"
が$var
空でない場合はtrueを返します。これはほとんどの場合、シェルスクリプトでチェックしたいものです。逆のチェックは、$var
未定義または空でない場合、になりますtest -z "${var-}"
。
次に、2番目の使用例として、変数var
が定義されているかどうか、空かどうかを確認します。これはあまり一般的ではない使用例であり、少し複雑です。Lionelsのすばらしい回答を読んで理解を深めることをお勧めします。
変数が設定されているかどうかを確認するには
var=""; [[ $var ]] && echo "set" || echo "not set"
$var
が空の文字列に設定されている場合、これは失敗します。
変数がバインドされているかどうかをテストする場合は、nounsetオプションをオンにした後でも、これはうまく機能します。
set -o noun set
if printenv variableName >/dev/null; then
# variable is bound to a value
else
# variable is unbound
fi
set -o nounset
、ではありませんset -o noun set
。これはexport
編集された変数に対してのみ機能します。また、元に戻すのが面倒な方法で設定が変更されます。
if test $# -gt 0; then printf 'arg <%s>\n' "$@"; fi
。