如何在 bash 中模拟 C++ `x=x&&f()`

How to emulate C++ `x=x&&f()` in bash

我到处写这个:

if (( $x == 0 )) ; then
    mycommand
    x=$?
fi

是否有 simpler/briefer 方法来实现 bash 的短路 &&

编辑: 我不关心 $x 的值,除了它的零值,即 success/failure.

(( x == 0 )) && { mycommand; x=$?; }
  • (( ... ))中你通常不需要在变量前加上$.

  • { ... } 是一个组命令,允许您作为一个单元执行多个命令,在本例中用作 && 运算符的 RHS。
    注意需要用;终止{ ... }中的最后一个命令(单行形式)。


通常,您可以直接使用 &&(逻辑与)和 ||(逻辑或) 链接命令,但请注意 这些(短路)运算符具有 相等 优先级 (并且像往常一样是左关联的)。

cmd1 && cmd2 && ... || cmdElse # first failing command triggers cmdElse

表示cmd1无条件执行,如果成功(退出代码0),所有后续命令只要成功就执行。
第一个 失败命令(非零退出代码)(如果有)会触发 || 子句。

相反,如果您想将 || 子句限制为特定命令,请使用组命令:

cmd1 && { cmd2 || cmd2Else; } # cmd2Else only executes if cmd2 gets to execute and fails

现在,cmdElse 仅在 cmd2 完全执行但失败时才被调用。

为了说明优先级相同的行为:

cmd1 || cmd2 && cmd3 # conceptually: (cmd1 || cmd2) && cmd3

cmd1无条件执行,失败则执行cmd2。如果成功,则执行cmd3
如果两者都失败,cmd3 永远不会执行。

所以,变量x只是上一条命令的结果?如果你的意思是你有一系列连续的几乎相同的块,比如:

if (( $x == 0 )) ; then my_command_1; x=$?; fi
....
if (( $x == 0 )) ; then my_command_N; x=$?; fi

那么,就这样组合你的命令

my_command_1 \
&& ... \
&& my_command_N

[更新]

另一方面,如果命令分散在整个脚本中,我会选择以下任一方法:

x=true
$x && my_command_1 || x=false
...
$x && my_command_2 || x=false

或者,更谨慎:

$do my_command_1 || do=:
...
$do my_command_2 || do=:

或者,更可能的是,通过函数:

function check_and_do { [ -z "$failed" ] && "$@" || failed=ouch; }

check_and_do my_command_1
....
check_and_do my_command_2