Shell工程化:错误处理机制

本文最后更新于 2026年7月8日 下午

Shell工程化:错误处理机制

一、为什么需要错误处理

Shell 脚本默认会按顺序执行命令,即使前面的命令执行失败,后续操作仍会继续进行,这可能导致数据异常、服务误操作等问题。

例如:

1
2
3
cp file.txt /backup/
rm temp.txt
systemctl restart nginx

cp 执行失败,后续命令依然会执行,因此工程化脚本必须具备错误检测和终止能力。

二、退出状态码(Exit Code)

Linux 中每条命令执行结束后都会返回退出状态码,可通过 $? 获取。

1
2
ls
echo $?

返回值说明:

返回值 含义
0 命令执行成功
非 0 命令执行失败

例如:

1
2
abc
echo $?

通常返回 127,表示命令不存在。

三、判断命令执行结果

推荐直接在 if 中执行命令,而不是依赖 $?

不推荐:

1
2
3
4
5
cp file.txt backup/

if [ $? -eq 0 ]; then
echo "成功"
fi

推荐:

1
2
3
4
5
if cp file.txt backup/; then
echo "复制成功"
else
echo "复制失败"
fi

这种写法更加安全,可避免中间命令覆盖退出状态码。

四、逻辑运算符

Shell 提供了简洁的错误控制方式。

成功后执行:

1
mkdir logs && echo "创建成功"

失败后执行:

1
cp file.txt backup/ || echo "复制失败"

组合使用:

1
cp file.txt backup/ && echo "成功" || echo "失败"

适用于简单流程控制。

五、set 安全选项

生产环境通常建议开启以下安全选项:

1
set -euo pipefail

各参数作用如下:

参数 作用
-e 任意命令失败立即退出
-u 使用未定义变量立即报错
pipefail 管道中任意命令失败,整个管道返回失败

例如:

1
2
3
4
5
6
7
#!/bin/bash

set -e

echo "开始"
abc
echo "结束"

执行到不存在的命令时,脚本会立即终止,不再继续执行。

注意: grep 未匹配内容时会返回状态码 1,在开启 set -e 后可能导致脚本退出,可根据业务场景使用 if grep -q ...grep ... || true 处理。

六、trap 退出处理

trap 可在脚本退出时自动执行指定操作,常用于资源清理。

例如:

1
trap 'echo "脚本结束"' EXIT

实际应用:

1
2
3
4
5
LOCK_FILE="/tmp/install.lock"

touch "$LOCK_FILE"

trap 'rm -f "$LOCK_FILE"' EXIT

无论脚本正常结束还是异常退出,都会自动删除锁文件,避免资源残留。

七、自定义错误处理函数

将错误处理统一封装,可提升代码复用性。

1
2
3
4
error_exit() {
log_error "$1"
exit 1
}

使用方式:

1
cp file.txt backup/ || error_exit "复制失败"

统一管理错误信息,也方便后续扩展日志记录、告警通知等功能。

八、推荐工程模板

建议所有 Shell 工程脚本采用统一初始化模板:

1
2
3
4
5
6
7
8
9
10
#!/bin/bash

set -euo pipefail

trap 'echo "脚本退出"' EXIT

LOG_DIR="./logs"
LOG_FILE="$LOG_DIR/app.log"

mkdir -p "$LOG_DIR"

后续可继续扩展:

  • 日志函数
  • 配置文件加载
  • 参数解析
  • 全局变量管理
  • 错误处理函数

形成统一、规范、易维护的工程化脚本框架。


Shell工程化:错误处理机制
http://example.com/42d458ae.html
作者
SHAO
发布于
2026年7月8日
许可协议