命令分组(&&、||、...)

Command grouping (&&, ||, ...)

我们目前在 /home/student/ 目录中。我们执行以下命令:

pwd; (ls) || { cd .. && ls student/; }  && cd student || cd / && cd ;

执行的命令是: pwd, ls, cd 学生, cd /, cd

这是我的想法:

到目前为止一切都清楚,我想。但是我不知道为什么要执行其他命令?如果有人能帮我分解一下,我将不胜感激。

&&|| 的运算符优先级严格从左到右。

因此:

pwd; (ls) || { cd .. && ls student/; }  && cd student || cd / && cd ;

...等同于...

pwd; { { { (ls) || { cd .. && ls student/; }; } && cd student; } || cd /; } && cd ; }

...以图形方式分解:

pwd; {                                      # 1
       {                                    # 2
         { (ls) ||                          # 3
                   { cd .. &&               # 4
                              ls student/;  # 5
                   };                       # 6
         } && cd student;                   # 7
       } || cd /;                           # 8
     } && cd ;                              # 9
  1. pwd 无条件发生
  2. (仅分组)
  3. ls 无条件地发生(在子 shell 中)。
  4. cd .. 如果 (3) 失败。
  5. ls student/ 如果 (3) 失败并且 (4) 成功
  6. (仅分组)
  7. cd student 如果 (3) 中的任何一个成功或 (4) 和 (5) 都成功。
  8. cd / 如果 [(3) 和 (4) 或 (5) 之一失败],或 [(7) 失败],则发生
  9. cd 如果 (7) 发生并成功,或 (8) 发生并成功。

使用明确的分组运算符是避免混淆的明智之举。避免编写如此难以阅读的代码更为明智。

(ls) is executed in a subshell, because the commands are separated with ";"

(ls) 由于括号的原因在子 shell 中执行。括号引入子壳。

But I have no idea why other commands are executed?

与您可能熟悉的其他编程语言不同,bash 不会给予 &&|| 更高的优先级。它们具有相同的优先级,并从左到右计算。

如果您有 a || b && c,在其他语言中这将被读作 a || { b && c; }。如果 a 为真,则 bc 都不会被计算。

在 bash 中,它被解析为 { a || b; } && c(严格的从左到右的优先顺序),因此当 a 为真时 b 被跳过但是 c 仍在评估中。