脚本创建临时目录后,如果中途命令失败或收到终止信号,散落在各分支里的清理代码很容易漏执行。可以把清理集中到 EXIT trap,并让信号处理先转换成约定的退出码。
环境:Bash 4.4+;Linux,或已安装新版 Bash 的 macOS;需要 mktemp 和 rm。
创建 cleanup-demo.sh:
#!/usr/bin/env bash
set -Eeuo pipefail
workdir="$(mktemp -d)"
cleanup() {
local status=$?
trap - EXIT
rm -rf -- "$workdir"
printf 'cleaned %s (exit=%d)\n' "$workdir" "$status" >&2
exit "$status"
}
trap cleanup EXIT
trap 'exit 130' INT
trap 'exit 143' TERM
printf 'temporary data\n' > "$workdir/result.txt"
printf 'working in %s\n' "$workdir"
# 用 false 模拟中途失败;改成 true 可观察成功退出。
false
运行并检查退出码:
chmod +x cleanup-demo.sh
./cleanup-demo.sh
printf 'status=%d\n' "$?"
false 使脚本以 1 退出,cleanup 中进入函数时的 $? 就是该状态;先保存它,再删除临时目录,最后原样退出。trap - EXIT 用于避免函数内的 exit 再次触发同一个 trap。
将 false 攻成 true 后,清理仍会执行,但退出码为 0。收到 SIGINT 或 SIGTERM 时则分别转换为常见的 130 和 143,随后仍由 EXIT trap 完成同一套清理。实际脚本如果还要释放挂载点、停止子进程或删除多个资源,可以继续放进 cleanup,但应先保存状态码,并避免让某个清理失败覆盖原始结果。