在 Bash 参考手册第 4.1 章中,关于测试命令的部分:
可以使用以下运算符组合表达式,按优先级降序列出。评估取决于参数的数量;见下文。当有五个或更多参数时,使用运算符优先级。
!expr 如果 expr 为假则为真。
( expr ) 返回 expr 的值。这可用于覆盖运算符的正常优先级。
...
由此看来,人们可以做类似的事情:
if [ 3 == 2 -a (2 == 2 -o 2 == 2) ];
Run Code Online (Sandbox Code Playgroud)
在这种情况下,括号 () 将覆盖正常优先级(首先是 -a,在这种情况下整个表达式将为 true),但是当我尝试运行它时,我得到:
/test.sh: line 3: syntax error near unexpected token `('
./test.sh: line 3: `if [ 3 == 2 -a (2 == 2 -o 2 == 2) ];'
Run Code Online (Sandbox Code Playgroud)
在的 POSIX 标准中,使用-a、、-o和括号被标记为已过时。但是,如果您确实想使用它们,则需要引用或转义括号,以便将它们作为参数传递给(又名),而不是由 shell 解释为语法:test[test
if [ 3 = 2 -a '(' 2 = 2 -o 2 = 2 ')' ]; then # OBSOLETE SYNTAX, DO NOT USE
Run Code Online (Sandbox Code Playgroud)
请注意,如果您将此代码放入http://shellcheck.net/,它将正确抛出警告SC2166。强烈建议阅读描述该警告的 wiki 页面(上面链接)。
避免过时的语法,您的行正确写为:
if [ 3 = 2 ] && { [ 2 = 2 ] || [ 2 = 2 ]; }; then
Run Code Online (Sandbox Code Playgroud)
请注意,字符串比较是=,而不是==。没有POSIX 标准 ==运算符test。
如果您想要仅 bash 扩展,请使用;[[代替 [这确实可以让你可靠地使用括号(并且也可以==可靠地使用,尽管使用=是更好的习惯,甚至可以开发与 POSIX 基线 shell 兼容的手指内存):
if [[ 3 = 2 && ( 2 = 2 || 2 = 2 ) ]]; then
Run Code Online (Sandbox Code Playgroud)