bash 使用 unset 与将变量设置为空

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12262696/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 22:37:46  来源:igfitidea点击:

Using unset vs. setting a variable to empty

bashvariablessyntax

提问by helpermethod

I'm currently writing a bash testing framework, where in a test function, both standard bash tests ([[) as well as predefined matchers can be used. Matchers are wrappers to '[[' and besides returning a return code, set some meaningful message saying what was expected.

我目前正在编写一个 bash 测试框架,其中在测试函数中,可以使用标准的 bash 测试 ( [[) 以及预定义的匹配器。匹配器是 '[[' 的包装器,除了返回返回码之外,还设置一些有意义的消息来说明预期的内容。

Example:

例子:

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

            return 1
    fi
}

So, when a matcher is used, and it fails, only then an error_message is set.

因此,当使用匹配器并且失败时,仅设置 error_message 。

Now, at some point later, I test whether the tests succeeded. If it succeeded, I print the expectation in green, if it failed in red.

现在,在稍后的某个时刻,我测试测试是否成功。如果成功,我用绿色打印期望值,如果失败用红色打印。

Furthermore, there may be an error_message set, so I test if a message exists, print it, and then unset it (because the following test may not set an error_message):

此外,可能有一个 error_message 设置,所以我测试一个消息是否存在,打印它,然后取消设置它(因为下面的测试可能没有设置一个error_message):

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

    unset -v error_message
fi

Now my question is, if it is better to unset the variable, or to just set it to '', like

现在我的问题是,是否最好取消设置变量,或者只是将其设置为 '',例如

error_message=''

Which one is better? Does it actually make a difference? Or maybe should I have an additional flag indicating that the message was set?

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

回答by cdarke

Mostly you don't see a difference, unless you are using set -u:

大多数情况下,您看不到区别,除非您使用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

So really, it depends on how you are going to test the variable.

所以实际上,这取决于您将如何测试变量。

I will add that my preferred way of testing if it is set is:

我将补充说,我的首选测试方式是:

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

or

或者

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

回答by Steven Penny

As has been said, using unset is different with arrays as well

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

$ foo=(4 5 6)

$ foo[2]=

$ echo ${#foo[*]}
3

$ unset foo[2]

$ echo ${#foo[*]}
2

回答by PdC

So, by unset'ting the array index 2, you essentially remove that element in the array and decrement the array size (?).

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

I made my own test..

我做了我自己的测试..

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

Which results in..

这导致..

3
0

So just to clarify that unset'ting the entire array will in fact remove it entirely.

所以只是为了澄清取消整个数组实际上会完全删除它。

回答by Jonathan H

Based on the comments above, here is a simple test:

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

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

Example:

例子:

$ 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