Answers:
尝试:
my_command || { echo 'my_command failed' ; exit 1; }
四个变化:
&&
为||
{ }
代替( )
;
在exit
和之后介绍{
之前和之后的空格}
既然你要打印的消息,只有当命令失败(非零值退出)退出你需要一个||
不是&&
。
cmd1 && cmd2
将cmd2
在cmd1
成功时运行(退出值0
)。在哪里
cmd1 || cmd2
将cmd2
在cmd1
失败时运行(退出值非零)。
使用( )
使其中的命令在子shell中运行然后exit
从那里调用a 会导致您退出子外壳而不是原始外壳,因此在原始外壳中继续执行。
为了克服这种使用 { }
bash需要最后两个更改。
{ (>&2 echo 'my_command failed') ; exit 1; }
其他答案很好地解决了直接问题,但您可能也对使用感兴趣set -e
。这样,任何失败的命令(例如if
测试之类的特定上下文之外)都将导致脚本中止。对于某些脚本,它非常有用。
set -e
关于何时工作以及何时不工作有很长而神秘的规则。(如果有人运行if yourfunction; then ...
,则set -e
永远不会在内部触发yourfunction
它调用的任何东西,因为该代码被视为“已检查”)。请参阅BashFAQ#105的练习部分,讨论此陷阱和其他陷阱(其中一些陷阱仅适用于特定的Shell版本,因此您需要确保针对可能用于运行脚本的每个发行版进行测试)。
还要注意,每个命令的退出状态都存储在shell变量$?中,您可以在运行命令后立即检查它。非零状态表示失败:
my_command
if [ $? -eq 0 ]
then
echo "it worked"
else
echo "it failed"
fi
echo "Just finished step A"
,却不知道那会echo
覆盖$?
以后要检查的内容。
如果您希望脚本中所有命令都具有这种行为,只需添加
set -e
set -o pipefail
在脚本的开头。这对选项告诉bash解释器在命令返回非零退出代码时退出。
但是,这不允许您打印退出消息。
trap
bash内置命令在退出时运行命令。
set -o pipefail
可能不是您期望的行为。仍然感谢您指出!
我破解了以下成语:
echo "Generating from IDL..."
idlj -fclient -td java/src echo.idl
if [ $? -ne 0 ]; then { echo "Failed, aborting." ; exit 1; } fi
echo "Compiling classes..."
javac *java
if [ $? -ne 0 ]; then { echo "Failed, aborting." ; exit 1; } fi
echo "Done."
在每条命令前都附上信息丰富的回显,并在每条命令后加上同一
if [ $? -ne 0 ];...
行。(当然,您可以根据需要编辑该错误消息。)
if ! javac *.java; then ...
-为什么要打扰$?
呢?
提供my_command
是经过规范设计的,即成功时返回0,则&&
与您想要的相反。你要||
。
还要注意,(
在bash中这似乎不适合我,但是我无法从自己所在的位置尝试。告诉我。
my_command || {
echo 'my_command failed' ;
exit 1;
}
如果要保留退出错误状态,并具有每行一个命令的可读文件,也可以使用:
my_command1 || exit $?
my_command2 || exit $?
但是,这不会打印任何其他错误消息。但是在某些情况下,无论如何该错误都会由失败的命令打印出来。
exit $?
。仅exit
将$?
其用作默认值。