捕获Bash脚本中被调用命令的所有错误信号

捕获Bash脚本中被调用命令的所有错误信号,bash,error-handling,signals,Bash,Error Handling,Signals,我们正在为构建服务器创建bash脚本。我们希望确保在脚本中执行bash命令时,返回的信号为0。如果没有,我们希望停止执行。到目前为止,我们的解决方案是: #some command if [ $? -ne 0 ] ; then #handle error fi 在每个可能导致此问题的命令之后。这使得代码相当长,看起来不太优雅。也许我们可以使用bash函数。虽然使用$?这可能有点棘手,我们仍然需要在每个命令之后调用该函数。有更好的办法吗?我已经研究了trap命令,但它似乎只对我正在编写的

我们正在为构建服务器创建bash脚本。我们希望确保在脚本中执行bash命令时,返回的信号为0。如果没有,我们希望停止执行。到目前为止,我们的解决方案是:

#some command
if [ $? -ne 0 ] ; then
    #handle error
fi

在每个可能导致此问题的命令之后。这使得代码相当长,看起来不太优雅。也许我们可以使用bash函数。虽然使用$?这可能有点棘手,我们仍然需要在每个命令之后调用该函数。有更好的办法吗?我已经研究了trap命令,但它似乎只对我正在编写的bash脚本进行信号处理,而不是调用任何命令。

实现这一点的健壮、规范的方法是:

#!/bin/bash
die() {
  local ret=$?
  echo >&2 "$*"
  exit "$ret"
}

./configure  || die "Project can't be configured"
make         || die "Project doesn't build"
make install || die "Installation failed" 
最简单、方便的方法是
set-e

#!/bin/bash
set -e     # Script will exit in many (but not all) cases if a command fails

./configure
make
make install
或等效(带有自定义错误消息):


对于后两种情况,作为条件语句或
&&
/
| |
一部分的任何命令都不会退出脚本,因此,当:

backup() {
  set -e
  scp backup.tar.gz user@host:/backup
  rm backup.tar.gz
}
backup
如果传输失败,将正确避免执行
rm
,稍后插入如下功能:

if backup
then
  mail -s "Backup completed successfully" user@example.com
fi

将使备份在出现故障时停止退出,并意外删除备份。

$?
是退出代码。出口代码和信号是不相关的。这是有效的!谢谢你的帮助。我可能会用第三个。ERR是否捕捉到任何非零信号?如果是这样,我是否也可以为其他信号设置陷阱,例如在SIGSEGV上显示特定消息,并使其优先于默认的ERR陷阱?ERR根本不会捕获任何信号。它在命令返回非零退出代码时触发。出口代码和信号是不同的。被信号SIGSEGV(11)终止的进程和以代码11退出的进程没有任何关系。好的。在编写脚本时,我们将记住这一点和最近的编辑。
if backup
then
  mail -s "Backup completed successfully" user@example.com
fi