Bash 抱怨缺少 ],而它就在那里

Bash 抱怨缺少 ],而它就在那里

我在 bash 脚本中有以下内容:

echo "status: [$status] and message: [$message]"
if [ "${status}" -eq 0 && "$message" = "ERROR" ];
then
        echo "Exit 0";
        exit 0
fi

# status: [0] message: [ERROR]

then但是,它给出了以下错误,并且ie下的逻辑exit 0永远不会被执行:

line 2: [: missing `]'

它似乎在抱怨缺少关闭],但是,它就在那里。我在这里缺少什么?

答案1

关闭]实际上并不存在。

你有:

cmd1 with its args && cmd2 with its args

cmd2当且仅当成功时才会运行cmd1

这里cmd1[命令,并且cmd2是名称存储在 中的命令$message

IOW,第一个命令是

[ "${status}" -eq 0

其中缺少结束语],第二个是:

"$message" = "ERROR" ]

你要

if [ "${status}" -eq 0 ] && [ "$message" = "ERROR" ]; then...

在类似于 Korn 的 shell(例如 bash)中,您还可以使用该[[...]]结构来代替[命令,该结构可以理解一种具有自己语法的微语言,而该语法恰好也有一个&&运算符。

if [[ $status -eq 0 && $message = ERROR ]]; then

但请注意,与 相反[,如果 的值$status可能受到攻击者的控制,则该漏洞会引入命令注入漏洞。

在 bash 中,[s-eq运算符不存在问题,因为它只接受十进制整数,而不接受像 for [[...]]'s这样的任意算术表达式-eq

bash-5.0$ status='a[$(echo>&2 Gotcha)]'
bash-5.0$ [[ $status -eq 0 ]]
Gotcha

此类问题也会影响(( status == 0 ))计算类 C 算术表达式的运算符(也来自 ksh):

bash-5.0$ (( status == 0 ))
Gotcha

¹ 这些算术表达式中还有 a &&,但是您不能在这里使用它,因为((...))它仅用于算术内容,因此您不能在那里进行字符串比较,您需要if (( status == 0 )) && [ "$message" = ERROR ].

答案2

您面临的问题是您正在使用[测试构造。此构造不支持参数中的布尔运算符,就像 korn-shell/bash-style [[-operator 那样,因此只能在[...中声明一个测试]

您可以通过以下方式连接两个条件&&- shell 级别的链接作为单独的测试,即

if [ "${status}" -eq 0 ] && [ "$message" = "ERROR" ];

或者使用更方便的[[ ... ]]- 运算符代替

if [[ "${status}" -eq 0 && "$message" = "ERROR" ]];

相关内容