为什么bash中未定义变量的比较是真的?

时间:2016-08-25 17:29:21

标签: bash

我正在学习bash的判决。 我测试与未定义变量的比较。其返回值为0。

我希望这是假的,就像任何与NaN的比较总是假的一样。 你能解释为什么这种比较的结果是真的吗?

unset UDEFINED_VAR_0
unset UDEFINED_VAR_1

echo "compare \${UDEFINED_VAR_0} = \${UDEFINED_VAR_1}"
[ ${UDEFINED_VAR_0} = ${UDEFINED_VAR_1} ]
IF_RESULT=$?
if [ ${IF_RESULT} -eq 0 ]; then
  COMMENT="success to compare \${UDEFINED_VAR_0} = \${UDEFINED_VAR_1}"
else
  COMMENT="failure to compare \${UDEFINED_VAR_0} = \${UDEFINED_VAR_1}"
fi
echo "$COMMENT"
echo "result is ${IF_RESULT}"

输出正在跟随,

compare ${UDEFINED_VAR_0} = ${UDEFINED_VAR_1}
success to compare ${UDEFINED_VAR_0} = ${UDEFINED_VAR_1}
result is 0

非常感谢。

2 个答案:

答案 0 :(得分:3)

如果不引用,则:

[ $empty_var1 = $empty_var2 ]

变为

[ = ]

被解析为:

的简写
[ -n = ]

检查=是否为非空字符串,它是,所以它返回true。

相反,如果你引用,那么:

[ "$empty_var1" = "$empty_var2" ]

变为

[ '' = '' ]

这是真的,因为这些字符串相等。

如果您想区分未设置设置为空值,请使用${var+val}

if [ -z "$var1" ]; then
  if [ -n "${var1+set}" ]; then
    echo "var1 is explicitly set to an empty (zero-byte) value"
  else
    echo "var1 is unset"
  fi
else
  echo "var1 is set to a non-empty value"
fi

答案 1 :(得分:1)

在情况1和2中,您正在创建语法错误,因为您没有使用引号。代码

[ "comparison_undefined_var" = ${UNDEFINED_VAR_0} ]

将转换为

[ "comparison_undefined_var" = ]

导致'一元运算符预期'错误消息,因为'='运算符是二元运算符,并且在右侧需要第二个参数,这里缺少。

如果您使用以下引用

[ "comparison_undefined_var" = "${UNDEFINED_VAR_0}" ]

这将被翻译为

[ "comparison_undefined_var" = "" ]

这样你就可以避免错误信息,代码将返回false而不会出现任何错误。

同样,在案例3和4中,代码

[ ${UNDEFINED_VAR} = ${UNDEFINED_VAR} ]

将转换为

[ = ]

我也希望有一条错误信息。但是,Charles Duffy在他的回答中指出,代码转换为

[ -n = ] 

测试字符串“=”是否为非空。它是非空的并且将返回true。但是,这不是,你想要测试的。相反,我建议写

[ "${UNDEFINED_VAR_0}" = "${UNDEFINED_VAR_1}" ]

代替。这将转化为

[ "" = "" ]

并将返回true。