我在 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" ]];