web-dev-qa-db-ja.com

未設定の使用と変数を空に設定

現在、bashテストフレームワークを作成しています。テスト関数では、標準のbashテスト([[)と事前定義されたマッチャーの両方を使用できます。マッチャーは '[['のラッパーであり、戻りコードを返すことに加えて、予期される内容を示す意味のあるメッセージを設定します。

例:

string_equals() {
    if [[ ! $1 = $2 ]]; then
            error_message="Expected '$1' to be '$2'."

            return 1
    fi
}

したがって、マッチャーが使用され、失敗した場合にのみ、error_messageが設定されます。

今、ある時点で、テストが成功したかどうかをテストします。成功した場合、期待値を緑色で印刷し、失敗した場合は赤色で印刷します。

さらに、error_messageが設定されている可能性があるため、メッセージが存在するかどうかをテストし、印刷してから設定を解除します(次のテストではerror_messageが設定されない可能性があるため)。

if [[ $error_message ]]; then
    printf '%s\n' "$error_message"

    unset -v error_message
fi

ここで私の質問は、変数を設定解除するか、単に ''に設定する方が良いかどうかです

error_message=''

どっちがいいですか?それは実際に違いを生みますか?または、メッセージが設定されたことを示す追加のフラグが必要ですか?

94
helpermethod

set -uを使用している場合を除き、ほとんど違いは見られません。

/home/user1> var=""
/home/user1> echo $var

/home/user1> set -u
/home/user1> echo $var

/home/user1> unset var
/home/user1> echo $var
-bash: var: unbound variable

したがって、実際には、変数をどのようにテストするかによって異なります。

それが設定されている場合のテストの好ましい方法は次のとおりです:

[[ -n $var ]]  # True if the length of $var is non-zero

または

[[ -z $var ]]  # True if zero length
132
cdarke

前述したように、unsetの使用は配列でも異なります

$ foo=(4 5 6)

$ foo[2]=

$ echo ${#foo[*]}
3

$ unset foo[2]

$ echo ${#foo[*]}
2
17
Steven Penny

したがって、配列インデックス2の設定を解除することで、配列内のその要素を本質的に削除し、配列サイズを減らします(?)。

私は自分でテストをしました。

foo=(5 6 8)
echo ${#foo[*]}
unset foo
echo ${#foo[*]}

結果は..

3
0

したがって、配列全体を設定解除すると、実際には完全に削除されることを明確にするだけです。

2
PdC

上記のコメントに基づいて、簡単なテストを次に示します。

isunset() { [[ "${!1}" != 'x' ]] && [[ "${!1-x}" == 'x' ]] && echo 1; }
isset()   { [ -z "$(isunset "$1")" ] && echo 1; }

例:

$ unset foo; [[ $(isunset foo) ]] && echo "It's unset" || echo "It's set"
It's unset
$ foo=     ; [[ $(isunset foo) ]] && echo "It's unset" || echo "It's set"
It's set
$ foo=bar  ; [[ $(isunset foo) ]] && echo "It's unset" || echo "It's set"
It's set
0
Sheljohn