Linux脚本可通过trap命令捕获SIGTERM、SIGHUP等信号,在退出前执行清理逻辑;需定义幂等的cleanup函数,用trap cleanup TERM INT绑定,并注意子shell继承、systemd信号传递及调试方法。

Linux 中脚本可通过捕获 SIGTERM(终止信号)或 SIGHUP 等信号,在退出前执行清理逻辑,比如删除临时文件、释放锁、刷新缓存等。核心是使用 trap 命令注册信号处理器。
用 trap 捕获 SIGTERM 并执行清理函数
trap 是 Shell 内置命令,用于指定收到特定信号时要运行的命令或函数。最常用的是在脚本退出前做清理:
- 定义一个清理函数(如
cleanup()),里面写清空缓存目录、关闭日志、还原状态等操作 - 用
trap cleanup TERM绑定该函数到SIGTERM - 如果还需响应 Ctrl+C,可加
trap cleanup INT
示例:
Linux 性能分析与调优专家,覆盖 CPU、内存、磁盘 I/O、网络、内核参数、编译优化、容器/K8s。适用场景:系统卡顿/高负载、内存不足/OOM/Swap 高、CPU 异常/iowait 高。
#!/bin/bash
CACHE_DIR="/tmp/myapp_cache"
cleanup() {
echo "正在清理缓存:$CACHE_DIR"
rm -rf "$CACHE_DIR"
exit 0
}
trap cleanup TERM INT
mkdir -p "$CACHE_DIR"
echo "缓存目录已创建,按 Ctrl+C 或 kill $$ 测试清理"
sleep 300
确保清理逻辑可靠且幂等
信号可能在任意时刻到达,清理函数需避免重复执行或残留状态:
- 用
trap '' TERM在清理开始时屏蔽再次接收SIGTERM,防止重入 - 检查缓存路径是否存在再删,避免报错中断;或用
rm -rf "$CACHE_DIR" 2>/dev/null - 若涉及多个资源(如文件+数据库连接),按反向顺序释放(先关连接,再删文件)
配合 systemd 服务时注意信号传递
若脚本作为 systemd 服务运行,systemctl stop 默认发 SIGTERM,但部分配置可能改用 SIGQUIT 或强制 SIGKILL(无法捕获):
- 在 service 文件中明确设置
Type=simple或Type=exec,并确认KillSignal=SIGTERM - 避免在
[Service]中设KillMode=none,否则信号不会传给主进程 - 测试时可用
kill -TERM $(pgrep -f "your_script.sh")验证 trap 是否生效
调试 trap 是否被触发
常见问题包括 trap 被覆盖、子 shell 中失效、或信号被忽略:
- 在清理函数开头加
echo "[DEBUG] cleanup triggered by $1" >&2,配合set -x查看执行流 - 确保 trap 写在脚本顶部(或至少在 fork 出子进程前),因为子 shell 不继承父 shell 的 trap
- 不要在循环中反复定义 trap,会导致覆盖;一次注册即可

















