webdevqa.jp.net

Bashで変数が設定されているかどうかを調べる方法は?

Bashで変数が設定されているかどうかはどうすればわかりますか?

たとえば、ユーザーが関数に最初のパラメータを指定したかどうかを確認する方法はありますか。

function a {
    # if $1 is set ?
}
1270
prosseek

(通常)正しい方法

if [ -z ${var+x} ]; then echo "var is unset"; else echo "var is set to '$var'"; fi

ここで${var+x}パラメータ展開 で、varname__が設定されていない場合は何も評価されず、それ以外の場合は文字列xname__に置き換えられます。

余談を引用する

引用符は省略できます(つまり、${var+x}の代わりに"${var+x}"と言うことができます)ので、これは引用符を必要としないものにのみ拡張されます(xname__に拡張されるため)。または何もしない(これは[ -z ]になり、これは[ -z "" ]と同じ値(true)に都合よく評価されます)。

しかし、引用符を安全に省略することができ、すぐに明白になるわけではありませんでしたが( この引用符の説明の最初の作者 主要なBashコーダーでもあることは明らかではありません) O(1)スピードペナルティという非常に小さいコストで、[ -z "${var+x}" ]のように引用符で解を書くのが良いでしょう。最初の著者は、この回答へのURLを提供するこのソリューションを使用してコードの横にコメントとしてこれを追加しました。これには、なぜ引用符を安全に省略できるかについての説明も含まれます。

(しばしば)間違った方法

if [ -z "$var" ]; then echo "var is blank"; else echo "var is set to '$var'"; fi

設定されていない変数と空の文字列に設定されている変数を区別しないため、これはしばしば間違っています。つまり、var=''の場合、上記のソリューションは "var is blank"を出力します。

Unsetと "空の文字列に設定"の区別は、ユーザーが拡張子または追加のプロパティのリストを指定する必要があり、それらを指定しないとデフォルトで空でない値になるため、空の文字列を指定する必要がある状況で重要です。スクリプトが空の拡張子または追加プロパティのリストを使用するようにします。

ただし、区別はすべてのシナリオで必須というわけではありません。そのような場合は[ -z "$var" ]は問題ありません。

1915
Lionel

Nullまたは0以外の文字列変数、つまり設定されている場合はチェックするには

if [ -n "$1" ]

それは-zの反対です。私は自分自身が-nよりも-zを使っているのに気づきました。

あなたはそれを使うだろう:

if [ -n "$1" ]; then
  echo "You supplied the first parameter!"
else
  echo "First parameter not supplied."
fi
756
mbrannig

以下は、パラメータが未設定空( "Null")、または値を設定のいずれであるかをテストする方法です。

+--------------------+----------------------+-----------------+-----------------+
|                    |       parameter      |     parameter   |    parameter    |
|                    |   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 |
+--------------------+----------------------+-----------------+-----------------+

出典: POSIX:パラメータ拡張

「代理」と表示されているすべての場合において、式は表示されている値に置き換えられます。 "assign"と表示されているすべての場合において、parameterはその値に割り当てられていて、これも式を置き換えます。

419
Jens

ここで述べるテクニックの大部分は正しいのですが、 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モードで未設定の変数をチェックするためにこの方法を使用してもエラーは発生しません。

188
Russell Harmon

以下のような方法があります。

if [ -z "$1" ]

$ 1がnullまたは未設定の場合、これは成功します。

173
ennuikiller

変数が空でないかどうかを確認するには、

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
61
phkoester

私はいつもPOSIXテーブルを 他の答え grokには遅いと思うので、ここに私の考えがあります:

   +----------------------+------------+-----------------------+-----------------------+
   |   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"  |          ""           |          ""           |
   +----------------------+------------+-----------------------+-----------------------+

各グループ(前にコロンがある場合とない場合)は同じsetケースとunsetケースを持っているため、異なる点はemptyケースの処理方法だけです。 。

前のコロンでは、emptyunsetのケースは同じなので、可能な場合はそれらを使用します(空のケースは矛盾するので、:=ではなく=を使用します)。

見出し:

  • setVARIABLEが空でないことを意味します(VARIABLE="something"
  • emptyVARIABLEが空またはnullであることを意味します(VARIABLE=""
  • 未設定VARIABLEが存在しないことを意味します(unset VARIABLE

値:

  • $VARIABLEは、結果が変数の元の値であることを意味します。
  • "default"は、結果が提供された置換文字列であったことを意味します。
  • ""は結果がnull(空の文字列)であることを意味します。
  • exit 127は、スクリプトが終了コード127で実行を停止することを意味します。
  • $(VARIABLE="default")は、結果が変数andの元の値であることを意味します。提供された置換文字列は将来の使用のために変数に割り当てられます。
53
deizel

最新バージョンの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
31
Seamus Connor
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
19
Paul Creasey

未設定の場合は終了します

これは私のために働きました。パラメータが設定されていない場合は、エラーメッセージを表示してスクリプトを終了するようにしました。

#!/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}"

実行するとエラーで戻ります

[email protected]:~$ ./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(comments)に捧げました。

参照 http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02

15
Jarrod Chesney

変数に空でない値が設定されているかどうかを確認するには、他の人が既に示しているように[ -n "$x" ]を使用します。

ほとんどの場合、空の値を持つ変数を設定されていない変数と同じように扱うことをお勧めします。 [ -n "${x+set}" ]setが設定されている場合は"${x+set}"xに展開され、xが設定されていない場合は空の文字列に展開されます)。

パラメータが渡されたかどうかを確認するには、$#をテストします。これは、関数(または関数に含まれていない場合はスクリプト)に渡されたパラメータの数です( Paul's answer を参照)。

14
Gilles

bashのmanページの "Parameter Expansion"セクションを読んでください。パラメータ展開は設定されている変数の一般的なテストを提供しませんが、パラメータが設定されていない場合にあなたができることがいくつかあります。

例えば:

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で何もしたくありません。設定されていない場合は終了してください)

14
chepner

Bashでは-vビルトインの中で[[ ]]を使うことができます。

#! /bin/bash -u

if [[ ! -v SOMEVAR ]]; then
    SOMEVAR='hello'
fi

echo $SOMEVAR
13
AlejandroVD

set -u を使用してスクリプト内で または空の が設定されていないことを確認したい場合は、次のように入力します。

if [ -z "${var-}" ]; then
   echo "Must provide var environment variable. Exiting...."
   exit 1
fi

[ -z "$var" ]の場合、通常のvar; unbound variableチェックはset -uで失敗しますが、varが失敗せずに設定解除されている場合、[ -z "${var-}" ] を空の文字列に展開します。

12
ecerulm

注意

私はbashタグのおかげで、Bashに重点を置いた答えを出しています。

短い答え

Bashで名前付き変数のみを扱っている限り、この関数は、たとえそれが空の配列であっても、変数が設定されているかどうかを常に教えてくれるはずです。

is-variable-set() {
    declare -p $1 &>dev/null
}

なぜこれが機能するのか

Bash(少なくとも3.0まで)では、varが宣言/設定変数の場合、declare -p varは、変数declareを現在の型と値に設定するvarコマンドを出力し、ステータスコード0(成功)を返します。 varが宣言されていない場合、declare -p varはエラーメッセージをstderrに出力し、ステータスコード1を返します。 &>/dev/nullを使用すると、通常のstdoutstderrの両方の出力が/dev/nullにリダイレクトされます。ステータスコードは変更されません。したがって、この関数はステータスコードのみを返します。

他の方法が(時々)Bashで失敗する理由

  • [ -n "$var" ]これは${var[0]}が空でないかどうかだけをチェックします。 (Bashでは、$var${var[0]}と同じです。)
  • [ -n "${var+x}" ]これは${var[0]}が設定されているかどうかだけをチェックします。
  • [ "${#var[@]}" != 0 ]これは、少なくとも1つの$varのインデックスが設定されているかどうかだけをチェックします。

このメソッドがBashで失敗したとき

これは名前付き変数($_を含む)に対してのみ機能します。特定の特殊変数($![email protected]$#$$$*$?$-$0$1$2など)はありません。これらはどれも配列ではないので、POSIXスタイルの[ -n "${var+x}" ]はこれらすべての特殊変数に対して機能します。しかし、関数が呼び出されると、多くの特別な変数が値や存在を変えるので、それを関数にラップすることに注意してください。

シェル互換性メモ

スクリプトに配列があり、できるだけ多くのシェルと互換性を持たせる場合は、typeset -pではなくdeclare -pを使用することを検討してください。私はkshが前者だけをサポートすると読んだことがありますが、これをテストすることはできませんでした。私は、Bash 3.0以降とZsh 5.5.1がそれぞれtypeset -pdeclare -pの両方をサポートしていることを知っています。しかし、これら2つのキーワード以外の違いについてはテストしていませんし、他のシェルについてもテストしていません。

スクリプトをPOSIX sh互換にする必要がある場合は、配列は使用できません。配列がなくても、[ -n "{$var+x}" ]は機能します。

Bashのさまざまなメソッドに対する比較コード

この関数は、渡されたコードの変数varevalを設定解除し、varevaldコードによって設定されているかどうかを判断するためにテストを実行し、最後にさまざまなテストのステータスコードを表示します。

test -v var[ -v var ]、および[[ -v var ]]は、POSIX標準の[ -n "${var+x}" ]と同じ結果になりますが、Bash 4.2以降が必要なため、スキップします。私がテストしたシェルのtypeset -pと同じであるため、declare -pもスキップします(Bash 3.0から5.0、およびZsh 5.5.1)。

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は、少なくとも3.0以降、Bashで名前付き変数をテストするのに(100%?)信頼性があります。
  • [ -n "${var+x}" ]はPOSIX準拠の状況では信頼できますが、配列を扱うことはできません。
  • 他のテストは、変数が空でないかどうかをチェックしたり、他のシェルで宣言された変数をチェックしたりするためのものです。しかし、これらのテストはBashスクリプトにもPOSIXスクリプトにも適していません。
8
Mark Haferkamp

上記の答えは、Bashオプションset -uが有効になっているとうまくいきません。また、それらは動的ではない、例えば、テストする方法は、「ダミー」という名前の変数が定義されているか?これを試して:

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.
}

関連: Bashで、変数が "-u"モードで定義されているかどうかをどうやってテストするか

4
kevinarpe

できるよ:

function a {
        if [ ! -z "$1" ]; then
                echo '$1 is set'
        fi
}
4
codaddict

変数が設定されているかどうかを知る最も簡単な方法は[[ -z "$var" ]]を使用することですが、そのオプション-zは未設定の変数と空の文字列に設定されている変数を区別しません。

$ set=''
$ [[ -z "$set" ]] && echo "Set" || echo "Unset" 
Unset
$ [[ -z "$unset" ]] && echo "Set" || echo "Unset"
Unset

変数の種類(env variable、parameterまたはregular variable)に従ってチェックするのが最善です。

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からの出力を抑制します。
4
Peregring-lk

私の好きな方法はこれです:

$var=10
$if ! ${var+false};then echo "is set";else echo "NOT set";fi
is set
$unset var
$if ! ${var+false};then echo "is set";else echo "NOT set";fi
NOT set

したがって、基本的に、変数が設定されると、それは「結果のfalseの否定」になります(true =になるものが設定されます)。

そして、もしそれが設定されていなければ、(空の結果がtrueに評価されるので)結果のtrueの否定になります(そのためfalse = "NOT set"として終わります)。

1
Aquarius Power

シェルでは、文字列の長さがゼロの場合にTrueになる-z演算子を使用できます。

設定されていない場合はデフォルトのMY_VARを設定する簡単なワンライナー。それ以外の場合は、メッセージを表示することもできます。

[[ -z "$MY_VAR" ]] && MY_VAR="default"
[[ -z "$MY_VAR" ]] && MY_VAR="default" || echo "Variable already set."
1
kenorb

これは私が毎日使うものです:

#
# Check if a variable is set
#   param1  name of the variable
#
function is_set()
{
    [[ -n "${1}" ]] && test -n "$(eval "echo "\${${1}+x}"")"
}

これはLinuxとSolarisの下でbash 3.0までうまく機能します。

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
0
fr00tyl00p

すべての回答をスキミングした後、これも機能します:

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を入れないと、空の値に設定されます。 $はこれが機能するために必要です。

0
Hatem Jaber

私はいつもこれを使います。というのも、このコードを初めて見る人は誰でも理解しやすいと思うからです。

if [ "$variable" = "" ]
    then
    echo "Variable X is empty"
fi

そして、空でないかどうかをチェックしたいのであれば。

if [ ! "$variable" = "" ]
    then
    echo "Variable X is not empty"
fi

それでおしまい。

0
mijnnaam

[email protected]で何かチェックしたいのなら、これを実行するための(はるかに)良いコードを見つけました。

 if [[$ 1 = ""]] 
 echo [$ 1は空白です] 
 else 
 echo '$ 1はいっぱいです' 
 fi 

なぜこれ全部? [email protected]の中身はすべてBashにありますが、デフォルトでは空白なので、test -ztest -nは役に立ちません。

更新: また、パラメータ内の文字数を数えることができます。

[$ {#1} = 0] 
 echo [$ 1は空白です] 
 else 
 echo '$ 1はいっぱいです' 
 fi 
0
Zlatan
if [[ ${!xx[@]} ]] ; then echo xx is defined; fi
0
Graham

私は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} ]
}

私はこの実装に最初にバグがあったので(JensとLionelの答えに触発されて)、私は別の解決策を思いついた。

# Ask for the properties of the variable - fails if not declared
function IsDeclared()
{
  declare -p $1 &>/dev/null
}

私はそれがより簡単で、よりashっていて理解しやすく/覚えやすいと感じています。テストケースはそれが同等であることを示しています。

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

テストケースはまた、local varNOTがvarを宣言することを示します( '='が後に続かない限り)。かなりの時間の間、私は変数をこのように宣言したと思っていました。ただ単に自分の意図を表明したことを今発見するために…それはノーオペレーションです、私は思います。

IsDeclared_Tricky xyz:1
IsDeclared_Tricky foo:1
IsDeclared_Trickyバー:0
IsDeclared_Trickyバズ:0
IsDeclared xyz:1
IsDeclared foo:1
IsDeclaredバー: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

Allを指定して呼び出すと、宣言された変数が必要になります。

こんにちは世界!

それ以外の場合

エラー:変数が宣言されていません:outputStr

0
Daniel S
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
0
solidsnack
[[ $foo ]]

または

(( ${#foo} ))

または

let ${#foo}

または

declare -p foo
0
Steven Penny