5.2 版本中的 bash 条件语句中分号现在是可选的吗?

问题描述 投票:0回答:1

以下 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 是否故意改变了这里的行为,或者这是一个错误?

bash
1个回答
0
投票

这是一个棘手的问题。

[[
,与
[
不同,是一个保留字:

$ 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 
[[' 命令的问题。

© www.soinside.com 2019 - 2024. All rights reserved.