如果任何命令返回一个非零值,则中止shell脚本?

我有一个Bash shell脚本来调用一些命令。 如果任何命令返回一个非零值,我希望shell脚本自动退出,返回值为1。

这可能没有明确检查每个命令的结果?

例如

dosomething1 if [[ $? -ne 0 ]]; then exit 1 fi dosomething2 if [[ $? -ne 0 ]]; then exit 1 fi 

将此添加到脚本的开头:

 set -e 

如果一个简单的命令以非零的退出值退出,这将导致shell立即退出。 一个简单的命令是任何命令,不是一个if,while或者直到testing的一部分,或者是一个&&或||的一部分 名单。

有关更多详细信息,请参见“set”内部命令的bash(1)手册页 。

我个人用“set -e”启动几乎所有的shell脚本。 当一个脚本在中间失败并且对脚本的其余部分进行假设时,脚本固执地继续下去是非常烦人的。

要添加到接受的答案:

请记住, set -e有时是不够的,特别是如果你有pipe道。

例如,假设你有这个脚本

  #!/bin/bash set -e ./configure > configure.log make 

…按预期工作:在configure错误中止执行。

明天你做一个看似微不足道的变化:

  #!/bin/bash set -e ./configure | tee configure.log make 

…现在它不工作。 这在这里解释,并提供一个解决方法(仅Bash):

   #!/斌/庆典
  设置-e 
   设置-o pipefail

   ./configure |  tee configure.log
  使

你的例子中的if语句是不必要的。 只是这样做:

 dosomething1 || exit 1 

如果你采取Ville Laurikari的build议,并使用set -e然后对于一些命令,你可能需要使用这个:

 dosomething || true 

|| true || true将使命令pipe道有一个true返回值,即使命令失败,所以-e选项不会终止脚本。

如果你有清理,你需要退出,你也可以使用伪信号ERR的“陷阱”。 这与捕获INT或任何其他信号的方式相同; 如果任何命令以非零值退出,bash将抛出ERR:

 # Create the trap with # trap COMMAND SIGNAME [SIGNAME2 SIGNAME3...] trap "rm -f /tmp/$MYTMPFILE; exit 1" ERR INT TERM command1 command2 command3 # Partially turn off the trap. trap - ERR # Now a control-C will still cause cleanup, but # a nonzero exit code won't: ps aux | grep blahblahblah 

或者,尤其是如果您使用“set -e”,则可能会陷入EXIT; 当脚本出于任何原因(包括正常结束,中断,由-e选项引起的退出等)时,您的陷阱将被执行。

-e或者在顶部set -e运行。

另外看看set -u

$? variables是很less需要的。 伪成语command; if [ $? -eq 0 ]; then X; fi command; if [ $? -eq 0 ]; then X; fi command; if [ $? -eq 0 ]; then X; fi应该总是写作, if command; then X; fi if command; then X; fi if command; then X; fi

$?的情况 是需要的时候需要检查多个值:

 command case $? in (0) X;; (1) Y;; (2) Z;; esac 

或当$? 需要重新使用或以其他方式操作:

 if command; then echo "command successful" >&2 else ret=$? echo "command failed with exit code $ret" >&2 exit $ret fi 

一个expression式

 dosomething1 && dosomething2 && dosomething3 

当其中一个命令以非零值返回时将停止处理。 例如,下面的命令永远不会打印“完成”:

 cat nosuchfile && echo "done" echo $? 1 
 #!/bin/bash -e 

应该足够了。

只是抛出另一个参考,因为有一个额外的问题马克Edgarsinput,这是一个额外的例子,涉及整体的话题:

 [[ `cmd` ]] && echo success_else_silence 

这与cmd || exit errcode相同 cmd || exit errcode为某人显示。

例如。 我想确保一个分区被卸载如果挂载:

 [[ `mount | grep /dev/sda1` ]] && umount /dev/sda1