金秋十月就要过去,美国大选就要开始。故事还是要继续,代码还是要写的。

上次我们讲到了 BASH 中的括号,这次我们一起 看一下,BASH 中的错误处理。

通常我们使用 BASH 都是在脚本文件里。脚本文件就是一个把许多 BASH 指令按照既定的逻 辑顺序进行编辑保存的文本文件。我们赋予该脚本文件可执行的权限,然后就可以在 BASH 环境下运行该脚本文件。我们当然希望脚本中的各个命令按照预想的方式执行,但是脚本也 会有各种各样的错误。此时,我们就要看看 BASH 是如何处理错误的。

  • 执行单个命令出错

默认时,BASH 不管命令是否返回错误状态,会接着执行下一条命令。如果脚本是在另外的 子进程里进行,用户是观察不到错误信息的。因此,BASH 提供了让命令碰到错误就停止的 设置。

执行 set -eset -o errexit 命令之后,其他命令如果执行之后返回错误,脚本就 会停止执行,不再执行下一条命令。

比如,

set -e
curl 404.html # 网址不存在,脚本停止
  • 脚本使用未初始化的变量

默认时,BASH 脚本遇到未初始化的变量时,会用空字符串代替之,并继续执行。这样会使 脚本带有很多隐患,是不安全的。BASH 也有方法让脚本遇到未初始化变量就停下来。

执行 set -uset -o nounset 命令之后,命令如果执行时遇到未初始化的变量,脚本 就会停止执行,不再执行下一条命令。

比如,

set -u
echo $UNSET # $UNSET 的值未知,脚本停止
  • 通过管道连接多个命令,有命令出错

默认时,不管管道过程中其他命令是否执行成功,只要最后一个命令返回成功,那么整个状 态就是成功。这个就忽略了管道中的错误。BASH 也提供了记录管道中错误的命令。

执行 set -o pipefail 命令之后,管道中各个命令执行时的错误都会被追踪。

比如,

set -o pipefail
curl 404.html | grep 'GNU' # curl 因为网址不存在,失败;grep 还是可以执行的;整
个命令失败。

当然,BASH 的 set 命令还可以设置其他处理命令执行错误的跟踪方式,不过这个留给大 家进一步探索。通常,我们在脚本的头部加上一行命令就可实现我们上面讲到的错误处理。

#!/usr/bin/env bash

set -euo pipefail

希望本文为你的 BASH 之旅带来帮助。