“test -v $ TESTENV”总是假,即使定义了TESTENV

时间:2018-03-05 22:28:55

标签: bash shell if-statement

我在Fedora 27下运行Bash 4.4.19,我有一个简单的脚本:

#!/bin/bash
TESTENV="Hello"
echo "$TESTENV"
if [ -v $TESTENV ]; then
    echo "Yup"
fi
echo "Done"

当我运行它时,会打印:

Hello
./myscript: line 3: [: Hello: binary operator expected
Done

所以,我将额外的括号添加到第3行,现在看起来像:

if [[ -v $TESTENV ]]; then

但是产生:

Hello
Done

什么给出了什么?我希望上面的一个/两个都能看到“Yup”。我尝试在引号中包装"$TESTENV",我也尝试使用-z运算符 - 但行为是相同的。

3 个答案:

答案 0 :(得分:5)

使用$,您使用变量的,而不是变量名称本身。你可能意味着:

if [[ -v TESTENV ]]; then
    echo "Yup"
fi

如果您定义了名为Hello的变量(例如Hello=hi),那么if条件就会成功,您可能根本没有注意到这个问题:)

答案 1 :(得分:0)

测试变量是否存在且不为null的最简单方法:

if [[ $TESTENV ]]; then ...

答案 2 :(得分:0)

我知道这是一个老问题,但我认为最重要的问题没有得到解答。单括号 [ 实际上是 test 命令的别名。这意味着 [ 不是语法。

因此,当 [ 有一个或多个试图计算返回空字符串的操作数时,它会抱怨它期待两个操作数(二进制)(“缺少操作数” 问题)。这就是为什么您会看到开发人员执行 [ x$foox = x$blahx ]xx 保证操作数永远不会计算为空字符串。

另一方面,双括号 [[ ]] 是一种语法,并且比 [ ] 强大得多。但是,需要注意的是,并非所有 POSIX shell 都支持 [[ ]]。此外,它没有 “缺少操作数” 问题,并且允许使用 >, <, >=, <=, !=, ==, &&, || 运算符使用更多类似 C 的语法。

我的建议如下:如果您的解释器是 #!/bin/bash,则使用 [[,但如果您想要可移植性,请使用 [

因此,在这种情况下,POSIX 兼容选项将是:

#!/bin/bash
TESTENV="Hello"
echo "$TESTENV"
if [ -v TESTENV ]; then
    echo "Yup"
fi
echo "Done"