fug*_*ive 4 shell bash shell-script
考虑以下:
root@debian-lap:/tmp echo "Step 1 " || echo "Failed to execute step 1" ; echo "Step 2"
Step 1
Step 2
root@debian-lap:/tmp
Run Code Online (Sandbox Code Playgroud)
如您所见,第 1 条和第 3 条echo
命令正常执行。
如果我的第一个命令失败了,我想停止脚本并exit
从中停止:
root@debian-lap:/home/fugitive echo "Step 1 " || echo "Failed to execute step 1" && exit 2 ; echo "Step 2"
Step 1
exit
fugitive@debian-lap:~$
Run Code Online (Sandbox Code Playgroud)
该exit
命令执行并退出 shell,即使第一个命令的退出代码为 0。我的问题是 - 为什么?
在翻译中,这不是说:
看着这个:
cmd foo1 || cmd foo2 && exit
不应该cmd foo2 and (&&) exit
只在cmd foo1
失败时执行吗?
我缺少什么?
我正在添加第二个示例,这是我真正想做的事情(仍然是虚拟测试)
root@debian-lap:/tmp/bashtest a="$(ls)" || echo "Failed" ; echo $a
test_file # < - This is OK
root@debian-lap:
root@debian-lap:/tmp/bashtest a="$(ls)" || echo "Unable to assign the variable" && exit 2; echo $a
exit
fugitive@debian-lap:~$ # <- this is confusing part
root@debian-lap:/tmp/bashtest a="$(ls /tmpppp/notexist)" || echo "Unable to assign the variable" ; echo $a
ls: cannot access /tmpppp/notexist: No such file or directory
Unable to assign the variable # <- This is also OK
root@debian-lap:
Run Code Online (Sandbox Code Playgroud)
因为最后执行的命令 (the echo
) 成功了。如果要对命令进行分组,使用if
语句会更清楚:
if ! step 1 ; then
echo >&2 "Failed to execute step 1"
exit 2
fi
Run Code Online (Sandbox Code Playgroud)
您也可以将错误消息分组并退出,{ ... }
但这有点难以阅读。但是,这确实保留了退出状态的确切值。
step 1 || { echo >&2 "step 1 failed with code: $?"; exit 2; }
Run Code Online (Sandbox Code Playgroud)
请注意,我将 更改&&
为分号,因为我假设即使错误消息失败您也想退出(并在 stderr 上输出这些错误以获得良好实践)。
对于if
保留退出状态的变体,您需要将代码添加到该else
部分:
if step 1; then
: OK, do nothing
else
echo >&2 "step 1 failed with code: $?"
exit 2
fi
Run Code Online (Sandbox Code Playgroud)
(这也使它与没有!
关键字的 Bourne shell 兼容)。
作为或为什么命令组喜欢做,标准说:
AND-OR 列表是由运算符
"&&"
和分隔的一个或多个管道的序列"||"
。运算符
"&&"
and"||"
应具有相同的优先级,并应使用左结合性进行评估。
这意味着,类似somecmd || echo && exit
的行为,就好像somecmd
和echo
被第一组合在一起,即 { somecmd || echo; } && exit
不 somecmd || { echo && exit; }
。