trap命令用于捕获信号并执行清理操作,最常用exit确保脚本退出前统一清理资源;语法为trap 'command' signal,需在脚本顶层设置以防被覆盖或失效。

在 Linux Shell 脚本中,trap 命令用于捕获特定信号(如 SIGINT、SIGHUP、SIGTERM 等),并在脚本收到这些信号时执行自定义清理操作,避免资源泄漏或状态不一致。最常用的是捕获退出前的信号,确保临时文件被删除、进程被终止、锁被释放等。
trap 捕获常见退出信号的写法
脚本启动后,可通过 trap 设置对信号的响应。关键信号包括:
-
EXIT:脚本正常或异常退出前触发(最常用,覆盖所有退出路径) -
INT:用户按 Ctrl+C 发送SIGINT -
TERM:外部用kill发送SIGTERM(默认 kill 信号) -
HUP:终端挂起或父进程退出时可能收到SIGHUP
基本语法为:trap 'command' SIGNAL [SIGNAL...]。例如:
使用 EXIT 保证统一清理入口
EXIT 是最可靠的选择,它不依赖具体信号来源,只要脚本结束(无论成功、失败、被中断)都会触发。适合集中处理清理逻辑:
- 删除临时目录:
rm -rf "$TMPDIR" - 关闭后台子进程:
kill $PID 2>/dev/null - 还原环境变量或 umask 设置
- 记录退出时间或状态到日志
注意:EXIT 处理器本身若出错(如命令不存在),不会影响脚本退出,但建议加 2>/dev/null 或简单判断避免干扰。
避免 trap 被覆盖或失效的细节
trap 的作用域受函数和子 shell 影响:
- 在函数内定义的
trap默认只在该函数内有效(除非用trap -p查看当前生效项) - 子 shell(如
(...)或管道中的命令)会继承父 shell 的 trap,但EXIT在子 shell 结束时也会触发一次 - 若需全局生效,应在脚本最外层(非函数内)设置,并避免重复调用同信号的
trap(后设置会覆盖前设置) - 用
trap -l可列出所有信号名与编号,用trap不带参数可查看当前已设 trap
实际脚本中的典型结构
一个健壮的脚本通常这样组织 trap:
#!/bin/bashTMPDIR=$(mktemp -d)
trap 'rm -rf "$TMPDIR"; exit 1' INT TERM
trap 'rm -rf "$TMPDIR"' EXIT
# 主逻辑
cp data.txt "$TMPDIR/"
./process "$TMPDIR/data.txt"
echo "Done."
这里分别用 INT/TERM 做快速清理并退出,EXIT 覆盖所有其他退出路径(包括成功完成),确保临时目录总被清理。











