【发布时间】:2016-12-24 00:13:56
【问题描述】:
我到处写这个:
if (( $x == 0 )) ; then
mycommand
x=$?
fi
有没有更简单/更简洁的方法来使用 bash 的短路 &&?
编辑:
我不关心$x 的价值,除了它的零性,即成功/失败。
【问题讨论】:
标签: bash short-circuiting
我到处写这个:
if (( $x == 0 )) ; then
mycommand
x=$?
fi
有没有更简单/更简洁的方法来使用 bash 的短路 &&?
编辑:
我不关心$x 的价值,除了它的零性,即成功/失败。
【问题讨论】:
标签: bash short-circuiting
(( x == 0 )) && { mycommand; x=$?; }
在(( ... )) 中,您通常不需要在变量前面加上$。
{ ... } 是一个组命令,允许您作为一个单元执行多个命令,在这种情况下用作&& 运算符的 RHS。
注意需要用; 终止{ ... } 中的最后一个命令(单行形式)。
通常,您可以直接将命令与&&(逻辑与)和||(逻辑或)链接起来,但请注意这些(短路)运算符具有equal优先级(并且像往常一样是左关联的)。
cmd1 && cmd2 && ... || cmdElse # first failing command triggers cmdElse
表示cmd1是无条件执行的,如果成功(退出代码0),所有后续命令只要它们也成功就执行。
first 失败的命令(非零退出代码)(如果有)会触发 || 子句。
相比之下,如果您想将 || 子句限制为特定命令,请使用组命令:
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
【讨论】:
$do my_command || do=: 是怎么回事? $do如何决定my_command是否执行?
do 要么未定义,要么 $do 评估为空=>您的命令已运行;或 do 在出现错误后被赋予值 :,并且 $do 计算为空命令 :(其参数,即您的命令,被忽略)。