116

我目前正在编写一个 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=''

哪一个更好?它真的有区别吗?或者也许我应该有一个额外的标志来指示消息已设置?

4

4 回答 4

148

大多数情况下,您看不到区别,除非您使用的是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
于 2012-09-04T12:54:07.617 回答
19

如前所述,使用 unset 与数组也不同

$ foo=(4 5 6)

$ foo[2]=

$ echo ${#foo[*]}
3

$ unset foo[2]

$ echo ${#foo[*]}
2
于 2014-10-18T16:52:01.230 回答
2

因此,通过取消设置数组索引 2,您实际上删除了数组中的该元素并减小了数组大小 (?)。

我自己做了测试。。

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

这导致..

3
0

因此,只是为了澄清取消设置整个数组实际上会完全删除它。

于 2018-04-12T07:52:12.240 回答
1

根据上面的评论,这是一个简单的测试:

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
于 2018-07-19T14:37:56.047 回答