确定 bash 中的变量是否为空(“”)的最佳方法是什么?
我听说有人建议我这样做if [ "x$variable" = "x" ]
那是不是正确的办法?(一定有更直接的方法)
答案1
如果变量未设置或设置为空字符串(“”),则返回 true。
if [ -z "${VAR}" ];
答案2
在 Bash 中,当您不关心对不支持它的 shell 的可移植性时,您应该始终使用双括号语法:
以下任何一项:
if [[ -z $variable ]]
if [[ -z "$variable" ]]
if [[ ! $variable ]]
if [[ ! "$variable" ]]
在 Bash 中,使用双方括号,引号不是必需的。您可以简化对变量的测试,做包含以下值:
if [[ $variable ]]
此语法与 ksh 兼容(至少与 ksh93 兼容)。它不适用于纯 POSIX 或较旧的 Bourne shell,例如 sh 或 dash。
看我的答案在这里和Bash常见问题/031有关双方括号和单方括号之间的差异的更多信息。
您可以测试某个变量是否未设置(与空字符串不同):
if [[ -z ${variable+x} ]]
其中“x”是任意的。
如果你想知道一个变量是否为空但未未设置:
if [[ -z $variable && ${variable+x} ]]
答案3
bash(以及任何与 POSIX 兼容的 shell)中的变量可以处于以下三种状态之一:
- 取消设置
- 设置为空字符串
- 设置为非空字符串
大多数时候您只需要知道变量是否设置为非空字符串,但有时区分未设置和设置为空字符串也很重要。
下面是如何测试各种可能性的示例,它可以在 bash 或任何与 POSIX 兼容的 shell 中运行:
if [ -z "${VAR}" ]; then
echo "VAR is unset or set to the empty string"
fi
if [ -z "${VAR+set}" ]; then
echo "VAR is unset"
fi
if [ -z "${VAR-unset}" ]; then
echo "VAR is set to the empty string"
fi
if [ -n "${VAR}" ]; then
echo "VAR is set to a non-empty string"
fi
if [ -n "${VAR+set}" ]; then
echo "VAR is set, possibly to the empty string"
fi
if [ -n "${VAR-unset}" ]; then
echo "VAR is either unset or set to a non-empty string"
fi
以下是同样的事情,但是以方便的表格形式呈现:
+-------+-------+-----------+
VAR is: | unset | empty | non-empty |
+-----------------------+-------+-------+-----------+
| [ -z "${VAR}" ] | true | true | false |
| [ -z "${VAR+set}" ] | true | false | false |
| [ -z "${VAR-unset}" ] | false | true | false |
| [ -n "${VAR}" ] | false | false | true |
| [ -n "${VAR+set}" ] | false | true | true |
| [ -n "${VAR-unset}" ] | true | false | true |
+-----------------------+-------+-------+-----------+
如果未设置,则构造扩展为空字符串;如果${VAR+foo}
设置为任何值(包括空字符串),则扩展为。VAR
foo
VAR
如果设置了(包括设置为空字符串)和未设置,则构造将扩展为值。这对于提供用户可覆盖的默认值很有用(例如,表示${VAR-foo}
除非变量已设置为某值,否则使用)。VAR
foo
${COLOR-red}
red
COLOR
之所以[ x"${VAR}" = x ]
经常被推荐用来测试变量是未设置还是设置为空字符串,是因为命令[
(也称为test
)的某些实现存在错误。如果VAR
将设置为类似的东西-n
,那么在给出时,某些实现会做错事[ "${VAR}" = "" ]
,因为第一个参数[
被错误地解释为-n
运算符,而不是字符串。
答案4
如果您有兴趣区分设置为空和未设置状态的情况,请查看 bash 的 -u 选项:
$ set -u
$ echo $BAR
bash: BAR: unbound variable
$ [ -z "$BAR" ] && echo true
bash: BAR: unbound variable
$ BAR=""
$ echo $BAR
$ [ -z "$BAR" ] && echo true
true