以下 bash 脚本:
#!/bin/bash
TEST_VAR=""
if [[ -z $TEST_VAR ]] then
echo "empty"
else
echo "$TEST_VAR"
fi
尽管“then”之前缺少一个分号,但在 bash 5.2 中不会抛出错误并成功完成,甚至返回
0
。
在运行 bash 5.1 或 5.0 的系统上运行上述脚本会按预期失败。
这是为什么呢? bash 在 5.2 版本中改变了他们的解析器吗?搜索后我找不到任何有关此更改的参考。 bash 是否故意改变了这里的行为,或者这是一个错误?
这是一个棘手的问题。
[[
,与[
不同,是一个保留字:
$ LANG=C type [
[ is a shell builtin
$ LANG=C type [[
[[ is a shell keyword
保留字,与命令/命令列表不同,不需要分号来标记其结束:
保留字是对 shell 有特殊含义的字。它们用于开始和结束 shell 的复合命令。
这意味着在
if [[ -z $TEST_VAR ]] then
中,[[ -z $TEST_VAR ]]
是命令列表中的第一个命令,它也恰好是保留关键字,因此标记其自己的结束,反过来,不需要分号来标记其结束。
因此,从语法上来说,你所经历的行为是完全有道理的。
您可以将
[[
视为自封闭 HTML 标签,例如 <br />
。
由于从语法的角度来看,这种行为是正确的,因此 5.2 之前的版本不表现出相同行为的事实应该被归类为错误,并且 changelog(在
bash-5.2-alpha
的更改列表中,第 265 行)似乎也这么认为:
米。修复了导致解析器不允许保留字跟随
[[' 命令的问题。((' and