条件失败时如何停止bash脚本?


11

在这里显示了使用||&&在一行中连接命令的执行:如何在bash脚本中检查apt-get错误?

如果某个条件失败,我试图停止执行脚本,

例如

false || echo "Obvious error because its false on left" && exit

它在这里打印Obvious error because its false on the left并退出我想要的控制台。

true || echo "This shouldn't print" && exit

在这里,没有回显打印,但是exit命令也运行了,即,控制台已关闭,exit由于未执行右侧的echo命令,该命令不应该不运行吗?还是默认情况下,&&运算符左侧的语句被认为是错误的?

编辑:我之前应该提到它,我的目的是回显错误,如果不清楚,则退出。对于我使用&&和||分组条件时捕获错误的特定情况,@ bodhi.zazen答案解决了该问题。

@takatakatek的答案使您对流量控制更加清楚,bash指南链接也非常出色

@muru答案很好地解释了为什么不使用set -e如果您希望通过使用perl和trap的替代方法抛出自定义错误消息,我认为这是更可靠的方法,并且从第二个bash脚本开始就可以使用它!


据我所知,脚本完成后就退出了。

Answers:


10

您可能想要(如钢螺丝刀所指出的)

true || { echo "This shouldn't print" && exit; }

否则您的脚本会一次读取一个条件

a或b然后退出

我认为您想要a或(b然后退出)?


4
实际上,您必须使用{ ... ; }(如@steeldriver所建议),否则,exit唯一的退出子shell,并且父shell继续执行脚本。
Gordon Davisson

14

问题是|| 和&&仅在条件失败时才跳过命令链中的后续节。如果您写出完整的块结构,则很有意义。您写的内容如下:

if ! true ; then
   echo "This shouldn't print"
else
   exit
fi

您想要的是:

if ! true ; then
   echo "This shouldn't print"
   exit
fi

使用Bash的快捷方式条件运算符时,最好避免混合使用它们。编写逻辑时,逻辑更容易理解,读者会欣赏您的良好风格。


2
是的,在我看来,这更多的是如何编写bash的条件
-derHugo

@takatakatek这使我更清楚为什么失败了。我同意逻辑很清楚,但这不是使用&&和||对条件进行分组的原因 是为了避免使用条件语句来表达它们?
kosol

@kosol是,&&和|| 结合两件事:测试上一条命令的退出状态,并指定要执行(对于&&)或跳过(对于||)的单个命令(或命令组)。它们在非常简单的情况下可能很有用,但不能替换完全表达的if ... then ... elif ... else ... fi块。我怀疑您可能没有意识到Bash没有在更复杂的语言中看到的真正的布尔类型。如果命令的退出状态为0(零),则Bash将其视为true / success。如果退出状态为非零,则Bash会将其视为false / failure
takatakatek

7

错误失败的最简单方法是使用bash的-e选项(set -e/bin/bash -e在shebang中)。但是,这并不容易发送自定义错误消息。有一些习惯用法可能会使它更简单:

die 香格里拉Perl

Perl有一个非常方便的die命令,该命令将消息打印到stderr并引发异常,通常会导致脚本终止。您可以模拟以下内容:

die () {
  ret=$?
  print "%s\n" "$@" >&2
  exit "$ret"
}

false || die "Obvious error because its false on left"
true || die "This shouldn't print"

trap ERR

trap <command>当收到信号,退出脚本(trap ... EXIT)或命令返回错误(trap ... ERR)时,该命令可用于运行命令。所以像这样:

trap 'ret=$?; printf "%s\n" "$ERR_MSG" >&2; exit "$ret"' ERR

然后:

ERR_MSG="Obvious error because its false here"
false
ERR_MSG="This shouldn't print"
true

无论哪种情况,我建议至少使用exit 1来指示脚本失败。平原exit将使用先前命令的退出状态,在这种情况下,前者将是echoor printf命令,通常会成功执行。像我在这里一样保存失败命令的退出状态将是一件很不错的事情。


6

您可以尝试通过以下方式尝试启动脚本

#!/bin/bash -e

-e确保脚本在某些错误返回时退出。然后可以避免特定的故障something || true

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.