如何在 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
我到处写这个:
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