简述 shell 中的错误处理

本文前面部分内容摘录自阮一峰老师的:Bash 脚本 set 命令教程,主要是文章写得太好了。

开启错误处理

使用 shell 中的错误处理有助于我们发现错误,更好的调试代码。

检测未定义变量

首先,set -u 可以在遇到未定义变量时抛出错误,而不是忽略它。比如:

echo $bar

这里的变量 bar 没有定义,shell 的默认方案是忽略掉它。这就可能带来隐藏的问题,所以通过 set -u 选项来强制报错:

set -u
echo $bar

此时会得到报错 ./test.sh: line 2: bar: unbound variable

报错时退出

如果某个命令执行错了,可能会导致后续一系列命令执行出错。既不利于调试,也会导致很多意想不到的结果,所以可以用 set -e 选项来强制报错时退出执行脚本。

set -e
bbbb
ssss

如果不加上 set -e 会得到两行报错,因为 bbbbssss 都是不存在的指令。而加上以后,这里只会有一个报错就立刻 exit 了。

需要注意的是,如果我们用管道的写法,得到的返回值是最后一个命令的返回值,如果中间的命令出错,是不能被 set -e 捕获的,比如:

set -e

bs | ls
echo 'reach here'

得到的输出结果将是:

aaa.sh: line 3: bs: command not found
test.sh
reach here

可见 bs 这个指令虽然不存在,但程序还是没有退出,而是执行到了结尾。因此 set -e 通常需要配合 set -o pipfail 来使用,这样管道中的任何一个指令出错,都会导致程序退出。

调试执行

如果想知道每一行都执行了什么代码,可以用 set -x 选项,通常我们在 Jenkins 等工具里可以这么用,方便追查问题。比如:

set -x
ls

我们会得到:

+ ls
test.sh

以加号开头的行就是文件的原始内容了。

top Created with Sketch.