在linux中捕获ctrl+c安全退出需用trap注册int信号处理器,执行cleanup函数清理临时文件、子进程和终端状态,并设exit 130;推荐同时捕获term和exit信号以覆盖所有退出路径。

在 Linux 中捕获 Ctrl+C 实现安全退出,核心是用 trap 命令拦截 SIGINT 信号,并在退出前执行清理逻辑。关键不在于“拦住不退出”,而在于“退出前把事做完”。
用 trap 注册 INT 信号处理器
Ctrl+C 默认发送 SIGINT(编号 2),脚本需在开头就注册处理函数:
- 写法: trap 'cleanup' INT —— 单引号内是命令字符串,cleanup 是提前定义好的函数名
- 必须先定义函数再注册 trap,否则运行时报 “command not found”
- 推荐同时捕获 TERM:trap 'cleanup' INT TERM,兼顾手动 kill 和终端中断
清理函数里只做真正必要的事
cleanup 函数要轻量、可靠、异步安全。常见操作包括:
- 删除临时文件或锁: rm -f /tmp/myapp.pid /var/run/myscript.lock
- 终止后台子进程: [[ -n "$SERVER_PID" ]] && kill "$SERVER_PID" 2>/dev/null
- 恢复终端状态: stty sane 2>/dev/null(避免 Ctrl+S/Ctrl+Q 锁死终端)
- 最后加 exit 130 —— 130 是 bash 中 Ctrl+C 的标准退出码,便于上层判断
注意子进程和作业控制
如果脚本启动了后台任务(如 python server.py &),默认情况下 trap 不会自动作用于子进程:
- 务必保存子进程 PID:python server.py & SERVER_PID=$!
- 启用作业控制:set -o monitor(加在脚本开头),让子 shell 继承 trap 设置
- 避免在 cleanup 里调用阻塞命令(如 curl、ssh),防止清理卡住无法退出
统一兜底:用 EXIT 捕获所有退出路径
除了 INT/TERM,脚本也可能因错误、自然结束或 exit 调用而退出。加一条 EXIT trap 可确保万无一失:
- trap 'echo "Script exiting at $(date)" >> /var/log/myscript.log' EXIT
- EXIT trap 在任何退出方式下都会触发(除非被更早的 trap 覆盖),适合日志记录、资源释放等通用清理
- 注意:EXIT trap 中不能依赖未导出的局部变量;若需传参,建议用全局变量或文件暂存











