如何判断Bash shell脚本中的字符串没有定义
如何判断Bash shell脚本中的字符串没有定义
如果我想检查空字符串,我会这样做
[ -z $mystr ]
但如果我想检查变量是否已经定义了呢?或者在Bash脚本中没有区别吗?
~> 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
当然,您会根据实际情况使用其中之一,将您想要的值放在“默认值”的位置,并直接使用扩展。
我认为你要找的答案是由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
)。