41 bash shell-script
我正在使用 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
Run Code Online (Sandbox Code Playgroud)
结果是:
line 322: syntax error near unexpected token `[['
Run Code Online (Sandbox Code Playgroud)
然后我尝试:
A=<0 or 1>
B=<0 or 1>
C=<0 or 1>
if [ ([ "$A" -eq "0" ]) || ([ "$B" -ne "0" ]) ] && [ "$C" -eq "0" ]; then ... fi
Run Code Online (Sandbox Code Playgroud)
结果是:
line 322: syntax error near unexpected token `[['
Run Code Online (Sandbox Code Playgroud)
部分问题是搜索结果是简单的例子,而不是带有复合条件的更复杂的例子。
如何((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
Run Code Online (Sandbox Code Playgroud)
Gil*_*il' 70
bash 的语法并不像 C 语言,即使它的一小部分受到 C 的启发。您不能简单地尝试编写 C 代码并期望它能够工作。
shell 的主要功能是运行命令。open-bracket 命令[
是一个执行单个测试的命令¹。你甚至可以把它写成test
(没有最后的右括号)。在||
与&&
运营商壳运营商,他们结合的命令,而不是测试。
所以当你写
[ [ "$A" -eq "0" ] || [ "$B" -ne "0" ] ] && [ "$C" -eq "0" ]
Run Code Online (Sandbox Code Playgroud)
这被解析为
[ [ "$A" -eq "0" ] ||
[ "$B" -ne "0" ] ] &&
[ "$C" -eq "0" ]
Run Code Online (Sandbox Code Playgroud)
这与
test [ "$A" -eq "0" ||
test "$B" -ne "0" ] &&
test "$C" -eq "0"
Run Code Online (Sandbox Code Playgroud)
注意到不平衡的括号了吗?是的,那不好。您使用括号的尝试具有相同的问题:伪括号。
将命令组合在一起的语法是大括号。解析大括号的方式需要在它们之前有一个完整的命令,因此您需要使用换行符或分号来终止大括号内的命令。
if { [ "$A" -eq "0" ] || [ "$B" -ne "0" ]; } && [ "$C" -eq "0" ]; then …
Run Code Online (Sandbox Code Playgroud)
还有一种替代方法是使用双括号。与单括号不同,双括号是特殊的 shell 语法。它们分隔条件表达式。在双括号内,您可以使用括号和运算符,如&&
and ||
。由于双括号是 shell 语法,shell 知道当这些运算符位于括号内时,它们是条件表达式语法的一部分,而不是普通 shell 命令语法的一部分。
if [[ ($A -eq 0 || $B -ne 0) && $C -eq 0 ]]; then …
Run Code Online (Sandbox Code Playgroud)
如果您的所有测试都是数字的,那么还有另一种方法来界定算术表达式。算术表达式使用非常类似于 C 的语法执行整数计算。
if (((A == 0 || B != 0) && C == 0)); then …
Run Code Online (Sandbox Code Playgroud)
您可能会发现我的 bash 支架入门很有用。
[
可以在普通 sh 中使用。[[
并且((
特定于 bash(以及 ksh 和 zsh)。
¹它还可以将多个测试与布尔运算符结合起来,但是这使用起来很麻烦并且有一些微妙的陷阱,所以我不会解释它。
Ste*_*itt 11
使用[[
:
if [[ ( "$A" -eq "0" || "$B" -ne "0" ) && "$C" -eq "0" ]]; then ...
Run Code Online (Sandbox Code Playgroud)
如果您愿意[
,可以使用以下方法:
if [ \( "$A" -eq "0" -o "$B" -ne "0" \) -a "$C" -eq "0" ]; then ...
Run Code Online (Sandbox Code Playgroud)
使用-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
Run Code Online (Sandbox Code Playgroud)