![当条件失败时如何停止 bash 脚本?](https://linux22.com/image/1148174/%E5%BD%93%E6%9D%A1%E4%BB%B6%E5%A4%B1%E8%B4%A5%E6%97%B6%E5%A6%82%E4%BD%95%E5%81%9C%E6%AD%A2%20bash%20%E8%84%9A%E6%9C%AC%EF%BC%9F.png)
这里显示使用一行中的||
and&&
来连接命令的执行:如何检查 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
这里,没有 echo 打印,但exit
命令也运行了,即控制台已关闭,命令不应该exit
运行,因为右侧的 echo 命令未执行?还是默认情况下,运算符左侧的语句被视为 false &&
?
编辑:我应该之前提到过,我的目的是回显错误,如果不清楚就退出。对于我使用 && 和 || 对条件进行分组时捕获错误的具体情况,@bodhi.zazen 的答案解决了这个问题。
@takatakatek 的回答更清楚地说明了流量控制,并且 bash 指南链接非常棒
@muru 的答案很好地解释了为什么不使用 set -e,如果您希望使用 perl 和 trap 的替代方法来抛出自定义错误消息,我认为这是一种更强大的方法,并且从我的第二个 bash 脚本开始我就使用它!
答案1
问题是,当条件不满足时,|| 和 && 只会跳过命令链中的一个后续节。如果你写出一个完整的块结构,那就完全说得通了。你写的内容如下:
if ! true ; then
echo "This shouldn't print"
else
exit
fi
你想要的是这个:
if ! true ; then
echo "This shouldn't print"
exit
fi
使用 Bash 的快捷条件运算符时,最好避免将它们混用。这样,在编写时,逻辑更容易理解,读者也会欣赏您的良好风格。
答案2
你可能想要(正如steeldriver指出的那样)
true || { echo "This shouldn't print" && exit; }
否则你的脚本每次只会读取一个条件
a 或 b 然后退出
我认为您想要 a 或 (b 和退出)?
答案3
你可以使用以下命令启动脚本:
#!/bin/bash -e
确保-e
脚本在返回 false(或任何非零数字)时立即退出。然后可以使用以下方法避免特定故障:something || true
或者,如果您想将错误检查推迟到脚本的后面,您可以使用set -e
:
#!/bin/bash
false # script continues happily
set -e
false # script stops
答案4
出错时失败的最简单方法是使用 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
将使用前一个命令的退出状态,在这些情况下将是echo
或printf
命令,这些命令通常会成功。像我在这里所做的那样保存失败命令的退出状态将是一件好事。