set -e在bash脚本中是什么意思?

我正在研究该脚本在Debian档案(.deb)文件解压缩之前执行的preinst文件的内容。

该脚本具有以下代码:

#!/bin/bash set -e # Automatically added by dh_installinit if [ "$1" = install ]; then if [ -d /usr/share/MyApplicationName ]; then echo "MyApplicationName is just installed" return 1 fi rm -Rf $HOME/.config/nautilus-actions/nautilus-actions.conf rm -Rf $HOME/.local/share/file-manager/actions/* fi # End automatically added section 

我的第一个查询是关于行:

 set -e 

我认为脚本的其余部分非常简单:它检查Debian / Ubuntu包pipe理器是否正在执行安装操作。 如果是,它会检查我的应用程序是否刚安装在系统上。 如果有,脚本打印出消息“MyApplicationName刚刚安装”并结束( return 1表示以“错误”结束,不是吗?)。

如果用户要求Debian / Ubuntu软件包安装我的软件包,那么脚本也会删除两个目录。

这是对的还是我错过了什么?

help set

  -e Exit immediately if a command exits with a non-zero status. 

但它不是很可靠,被认为是不好的做法,更好地使用:

 trap 'do_something' ERR 

当发生错误时运行do_something函数。

http://mywiki.wooledge.org/BashFAQ/105

set -e在命令或pipe道有错误的情况下停止执行脚本 – 这与默认的shell行为相反,即忽略脚本中的错误。 在terminal中键入help set以查看此内置命令的文档。

根据bash – Set Builtin手册,如果设置了 -e / errexit ,如果一个pipe道由一个简单的命令组成 , 一个列表或一个复合命令返回一个非零的状态,shell立即退出。

默认情况下,pipe道的退出状态是pipe道中最后一个命令的退出状态,除非pipefail选项被启用(默认情况下禁用)。

如果是这样,pipe道的最后(最右边)命令的返回状态以非零状态退出,如果所有命令都成功退出,则为零。

如果您想在退出时执行某些操作,请尝试定义trap ,例如:

 trap onexit EXIT 

其中onexit是你的函数在退出,如下面打印简单的堆栈跟踪 :

 onexit(){ while caller $((n++)); do :; done; } 

有类似的选项-E / errtrace ,它会陷入错误,例如:

 trap onerr ERR 

例子

零状态示例:

 $ true; echo $? 0 

非零状态示例:

 $ false; echo $? 1 

否定状态示例:

 $ ! false; echo $? 0 $ false || true; echo $? 0 

testingpipefail被禁用:

 $ bash -c 'set +o pipefail -e; true | true | true; echo success'; echo $? success 0 $ bash -c 'set +o pipefail -e; false | false | true; echo success'; echo $? success 0 $ bash -c 'set +o pipefail -e; true | true | false; echo success'; echo $? 1 

testing与启用pipefail

 $ bash -c 'set -o pipefail -e; true | false | true; echo success'; echo $? 1 

我在谷歌search时发现了这个问题,试图找出退出状态是由于set -e而中止的脚本。 答案对我来说并不明显, 因此这个答案。 基本上, set -e放弃命令(例如shell脚本)的执行,并返回失败命令(例如,内部脚本,而不是外部脚本)的退出状态码。

例如,假设我有一个shell脚本outer-test.sh

 #!/bin/sh set -e ./inner-test.sh exit 62; 

inner-test.sh的代码是:

 #!/bin/sh exit 26; 

当我从命令行运行outer-script.sh ,外部脚本终止于内部脚本的退出代码:

 $ ./outer-test.sh $ echo $? 26