我正在研究这个preinst文件的内容,该脚本在包从Debian归档文件(.deb)文件解压缩之前执行该文件。
脚本代码如下:
#!/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包管理器是否正在执行安装操作。如果是,它将检查我的应用程序是否刚刚安装到系统上。如果有,脚本打印消息“MyApplicationName刚刚安装”并结束(返回1意味着以“错误”结束,不是吗?)
如果用户要求Debian/Ubuntu包系统安装我的包,脚本还会删除两个目录。
是这样吗,还是我漏掉了什么?
我在试图弄清楚由于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
根据bash - Set Builtin手册,如果设置了-e/errexit,当由单个简单命令、列表或复合命令组成的管道返回非零状态时,shell立即退出。
默认情况下,管道的退出状态是管道中最后一个命令的退出状态,除非启用了pipefail选项(默认情况下禁用)。
如果是,最后一个(最右边)退出命令的管道返回状态为非零状态,如果所有命令都成功退出,则为零。
如果你想在退出时执行一些东西,尝试定义trap,例如:
trap onexit EXIT
其中onexit是你的函数,在退出时做一些事情,如下所示,打印简单的堆栈跟踪:
onexit(){ while caller $((n++)); do :; done; }
还有类似的选项-E/errtrace,它会捕获ERR,例如:
trap onerr ERR
例子
零状态示例:
$ true; echo $?
0
非零状态示例:
$ false; echo $?
1
否定地位的例子:
$ ! false; echo $?
0
$ false || true; echo $?
0
禁用pipefail测试:
$ 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
启用pipefail测试:
$ bash -c 'set -o pipefail -e; true | false | true; echo success'; echo $?
1
我在试图弄清楚由于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