多个逻辑运算符 ((A || B) && C) 和“意外标记附近的语法错误”

多个逻辑运算符 ((A || B) && C) 和“意外标记附近的语法错误”

我正在使用 Bash 3,并且正在尝试形成一个条件。在 C/C++ 中,它非常简单:((A || B) && C).在 Bash 中,结果并非如此(我认为 Git 作者在转向其他工作之前一定已经贡献了这段代码)。

这是行不通的。请注意,这<0 or 1>不是一个字符串文字;它表示 0 或 1(通常来自grep -i)。

A=<0 or 1>
B=<0 or 1>
C=<0 or 1>
if [ [ "$A" -eq "0" ] || [ "$B" -ne "0" ] ] && [ "$C" -eqe "0" ]; then ... fi

其结果是:

line 322: syntax error near unexpected token `[['

然后我尝试:

A=<0 or 1>
B=<0 or 1>
C=<0 or 1>
if [ ([ "$A" -eq "0" ]) || ([ "$B" -ne "0" ]) ] && [ "$C" -eq "0" ]; then ... fi

结果是:

line 322: syntax error near unexpected token `[['

部分问题是搜索结果是简单的示例,而不是具有复合条件的更复杂的示例。

如何((A || B) && C)在 Bash 中执行简单操作?


我准备好展开它并在多个块中重复相同的命令:

A=<0 or 1>
B=<0 or 1>
C=<0 or 1>

if [ "$A" -eq "0" ] && [ "$C" -eq "0" ]; then
    ...
elif [ "$B" -ne "0" ] && [ "$C" -eq "0" ]; then
    ... 
fi

答案1

bash 的语法与 C 不同,即使其中一小部分受到 C 的启发。您不能简单地尝试编写 C 代码并期望它能够工作。

shell 的要点是运行命令。开括号命令[是执行单个测试的命令。您甚至可以将其写为test(不带最后的右括号)。||和运算符&&是 shell 运算符,它们组合起来命令,不是测试。

所以当你写的时候

[ [ "$A" -eq "0" ] || [ "$B" -ne "0" ] ] && [ "$C" -eq "0" ]

被解析为

[ [ "$A" -eq "0" ] ||
[ "$B" -ne "0" ] ] &&
[ "$C" -eq "0" ]

这与以下相同

test [ "$A" -eq "0" ||
test "$B" -ne "0" ] &&
test "$C" -eq "0"

注意到不平衡的括号了吗?是的,那不好。您对括号的尝试也有同样的问题:虚假括号。

将命令组合在一起的语法是大括号。解析大括号的方式需要在它们之前有一个完整的命令,因此您需要使用换行符或分号来终止大括号内的命令。

if { [ "$A" -eq "0" ] || [ "$B" -ne "0" ]; } && [ "$C" -eq "0" ]; then …

还有一种替代方法是使用双括号。与单括号不同,双括号是特殊的 shell 语法。他们划定界限条件表达式。在双括号内,您可以使用括号和运算符,例如&&||。由于双括号是 shell 语法,因此 shell 知道当这些运算符位于括号内时,它们是条件表达式语法的一部分,而不是普通 shell 命令语法的一部分。

if [[ ($A -eq 0 || $B -ne 0) && $C -eq 0 ]]; then …

如果您所有的测试都是数字的,那么还有另一种方法可以界定算术表达式。算术表达式使用非常类似于 C 的语法执行整数计算。

if (((A == 0 || B != 0) && C == 0)); then …

你可能会发现我的 bash 支架底漆有用。

[可以在普通 sh 中使用。[[并且((特定于 bash(以及 ksh 和 zsh)。

1它还可以将多个测试与布尔运算符结合起来,但这使用起来很麻烦,并且有微妙的陷阱,所以我不会解释它。

答案2

使用[[

if [[ ( "$A" -eq "0" || "$B" -ne "0" ) && "$C" -eq "0" ]]; then ...

如果您愿意[,可以执行以下操作:

if [ \( "$A" -eq "0" -o "$B" -ne "0" \) -a "$C" -eq "0" ]; then ...

答案3

使用-o运算符而不是嵌套的 ||。-a如果需要,您还可以在其他语句中使用 && 来替换。

   EXPRESSION1 -a EXPRESSION2
          both EXPRESSION1 and EXPRESSION2 are true

   EXPRESSION1 -o EXPRESSION2
          either EXPRESSION1 or EXPRESSION2 is true


if [  "$A" -eq "0" -o "$B" -ne "0"  ] && [ "$C" -eq "0" ]; then echo success;fi

相关内容