如何判断Bash shell脚本中的字符串没有定义

72 浏览
0 Comments

如何判断Bash shell脚本中的字符串没有定义

如果我想检查空字符串,我会这样做

[ -z $mystr ]

但如果我想检查变量是否已经定义了呢?或者在Bash脚本中没有区别吗?

admin 更改状态以发布 2023年5月22日
0
0 Comments

~> if [ -z $FOO ]; then echo "EMPTY"; fi
EMPTY
~> FOO=""
~> if [ -z $FOO ]; then echo "EMPTY"; fi
EMPTY
~> FOO="a"
~> if [ -z $FOO ]; then echo "EMPTY"; fi
~> 

选项-z也适用于未定义的变量。为了区分已定义和未定义的变量,可以使用此处列出的内容或更清晰的解释,可以参考此处

最清晰简洁的方式是使用扩展,就像这些示例中的方式一样。要获取所有选项,请查看手册中的参数扩展部分。

备选词:

~$ unset FOO
~$ if test ${FOO+defined}; then echo "DEFINED"; fi
~$ FOO=""
~$ if test ${FOO+defined}; then echo "DEFINED"; fi
DEFINED

默认值:

~$ FOO=""
~$ if test "${FOO-default value}" ; then echo "UNDEFINED"; fi
~$ unset FOO
~$ if test "${FOO-default value}" ; then echo "UNDEFINED"; fi
UNDEFINED

当然,您会根据实际情况使用其中之一,将您想要的值放在“默认值”的位置,并直接使用扩展。

0
0 Comments

我认为你要找的答案是由Vinko答案暗示(如果没有说明),虽然它并没有简单明了地说明。要区分VAR是否设置为空,可以使用以下命令:

if [ -z "${VAR+xxx}" ]; then echo "VAR is not set at all"; fi
if [ -z "$VAR" ] && [ "${VAR+xxx}" = "xxx" ]; then echo "VAR is set but empty"; fi

你可以将第二行的两个测试结合为一个:

if [ -z "$VAR" -a "${VAR+xxx}" = "xxx" ]; then echo "VAR is set but empty"; fi

然而,如果你阅读Autoconf的文档,你会发现他们不建议使用'-a'将术语组合起来,而是推荐使用单独的简单测试与&&组合。我没有遇到过系统有问题的情况;但这并不意味着它们以前不存在(尽管它们可能在遥远的过去不如现在稀有)。

你可以在Bash手册中找到这些和其他相关的shell参数扩展test[ 命令和条件表达式的细节。


最近我通过电子邮件收到了有关这个答案的问题:

你使用了两个测试,我理解第二个测试很好,但第一个测试我不理解。更确切地说,我不理解变量扩展的必要性

if [ -z "${VAR+xxx}" ]; then echo "VAR is not set at all"; fi

这个不是有效的吗?

if [ -z "${VAR}" ]; then echo "VAR is not set at all"; fi

这是一个合理的问题-答案是“不,你更简单的方法不能做同样的事情”。

假设在你的测试之前,我写了这个:

VAR=

你的测试将说“VAR根本没有设置”,但是我的测试将(凭借它不输出任何东西的暗示)说“VAR被设置了,但它的值可能为空”。尝试运行这个脚本:

(
unset VAR
if [ -z "${VAR+xxx}" ]; then echo "JL:1 VAR is not set at all"; fi
if [ -z "${VAR}" ];     then echo "MP:1 VAR is not set at all"; fi
VAR=
if [ -z "${VAR+xxx}" ]; then echo "JL:2 VAR is not set at all"; fi
if [ -z "${VAR}" ];     then echo "MP:2 VAR is not set at all"; fi
)

输出结果是:

JL:1 VAR is not set at all
MP:1 VAR is not set at all
MP:2 VAR is not set at all

在第二组测试中,变量被设置了,但它被设置为空值。这是${VAR=value}${VAR:=value}符号所做出的区分。对于${VAR-value}${VAR:-value}以及${VAR+value}${VAR:+value}等,同理。


正如Gili在他的答案中指出的,如果你在bash中使用set -o nounset选项运行,那么上面的基本答案将失败并显示“unbound variable”。很容易解决:

if [ -z "${VAR+xxx}" ]; then echo "VAR is not set at all"; fi
if [ -z "${VAR-}" ] && [ "${VAR+xxx}" = "xxx" ]; then echo "VAR is set but empty"; fi

或者你可以使用set +u取消set -o nounset选项(set -u等同于set -o nounset)。

0