trap是linux shell脚本中实现异常捕获与自动清理的核心机制,需在开头注册int/term/hup/exit信号,用独立函数封装清理逻辑并export关键变量,配合set -euo pipefail和err trap实现命令级错误响应。

在 Linux Shell 脚本中,trap 是实现异常捕获与自动清理的核心机制。它不阻止错误或中断,而是确保无论脚本因何退出(Ctrl+C、kill、命令失败、正常结束),都能执行预定义的清理逻辑——比如删临时文件、终止子进程、释放端口、还原配置等。
一、必须在开头注册关键信号
trap 命令需放在脚本最靠前的位置(变量声明后、主逻辑前),否则信号到达时还未注册,就会直接走默认行为(如终止进程、残留资源)。
- 推荐一次性绑定四类信号:INT TERM HUP EXIT
- INT:对应 Ctrl+C,用户主动中断
- TERM:systemd 或 kill -15 发送的标准终止请求
- HUP:SSH 断开、终端关闭、systemd restart 时极易触发,常被遗漏但危害大
- EXIT:兜底信号,脚本退出前必触发(无论成功、失败、被杀)
二、把清理逻辑写成独立函数
避免在 trap 中直接写长命令;用函数封装更清晰、可测试、易复用。注意:trap 内部以子 shell 方式执行,无法访问父 shell 的局部变量,所以关键变量(如 TMPDIR、PID)要提前 export。
在无 root/sudo 权限的环境(云容器、VPS、隔离主机)中安装并配置 OpenClaw 浏览器工具的 headless Chrome。适用场景:...
- 示例 cleanup 函数:
[ -n "$TMPDIR" ] && rm -rf "$TMPDIR"
[ -n "$PID" ] && kill -TERM "$PID" 2>/dev/null || :
echo "Exited at $(date)" >> /var/log/myscript.log
}
- 注册方式:trap cleanup INT TERM HUP EXIT
三、用 ERR 捕获命令级失败并即时响应
ERR 是一个“伪信号”,在任意命令返回非零状态时触发,适合做错误定位和快速回滚。但要注意配合 set -e 才能稳定生效。
- 必须在 set -e 之前设置 trap ERR,否则可能不触发
- 启用严格模式:set -euo pipefail(推荐加在脚本首行)
- ERR 不捕获管道中间失败(如 cmd1 | cmd2,cmd1 失败但 cmd2 成功),需加 set -o pipefail 补全
- 示例:trap 'echo "Error on line $LINENO"; cleanup; exit 1' ERR
四、区分正常退出与异常退出(可选但实用)
EXIT 总是执行,但有时需判断是成功结束还是中途出错。$? 在 trap 内不可靠(它反映的是 trap 上一条命令的退出码),稳妥做法是用自定义变量控制。
- 主流程末尾设:exit_code=0
- 出错分支设:exit_code=1(并在那里调用 cleanup 或留待 EXIT 处理)
- EXIT 中检查:trap 'if [ "$exit_code" != "0" ]; then echo "Aborted"; fi; cleanup' EXIT
- 更推荐:清理动作本身保持幂等(如 rm -f、kill -TERM 无副作用),无需区分也安全










