ctrl+c默认发送sigint终止进程,需用trap 'cleanup_func' int捕获并执行清理逻辑;cleanup_func须提前定义,包含删锁、杀子进程、恢复终端等操作,并建议加set -o monitor和exit 130确保可靠退出。

在Linux运维脚本中,Ctrl+C会向当前前台进程组发送SIGINT信号,默认行为是终止进程。但很多关键任务(比如清理临时文件、关闭连接、重置状态、释放端口)不能直接退出,必须捕获该信号并执行自定义清理逻辑。
用trap命令注册中断处理函数
trap是Shell内置命令,用于指定接收到特定信号时要执行的命令或函数。捕获Ctrl+C的核心写法是:
-
trap 'cleanup_func' INT—— 在脚本开头注册,当收到SIGINT(即Ctrl+C)时调用cleanup_func -
cleanup_func需提前定义,里面放所有必须完成的善后操作,如rm -f /tmp/my.lock、kill $CHILD_PID 2>/dev/null、echo "exiting gracefully..." >&2 - 务必在trap前定义函数,否则执行时会报“command not found”
常见陷阱与正确实践
很多脚本看似加了trap,但实际仍无法可靠清理,问题常出在以下几点:
- 未显式启用作业控制(
set -o monitor)时,子shell或管道中的进程可能不继承trap,建议在脚本开头加上 - 不要在trap handler里调用可能阻塞或不可靠的命令(如
curl、ssh),避免清理卡住 - 若脚本启动了后台子进程(如
python server.py &),需保存其PID,并在trap中kill它;否则子进程会变成孤儿继续运行 - 可配合
exit确保脚本真正退出:trap 'cleanup_func; exit 130' INT(130是bash中Ctrl+C的标准退出码)
一个完整可用的模板
以下是一个轻量、健壮的运维脚本中断处理结构:
在无 root/sudo 权限的环境(云容器、VPS、隔离主机)中安装并配置 OpenClaw 浏览器工具的 headless Chrome。适用场景:...
#!/bin/bash
<h1>清理函数:删除锁、停止子进程、恢复终端设置等</h1><p>cleanup() {
echo -e "\n[INFO] Caught SIGINT, cleaning up..."
rm -f /var/run/myscript.pid
[[ -n "$SERVER_PID" ]] && kill "$SERVER_PID" 2>/dev/null
stty sane 2>/dev/null # 恢复终端
}</p><h1>注册信号处理器</h1><p>trap cleanup INT TERM</p><h1>记录主进程PID(可选,便于其他脚本识别)</h1><p>echo $$ > /var/run/myscript.pid</p><h1>启动一个长期运行的任务(示例)</h1><p>python3 -m http.server 8000 &
SERVER_PID=$!</p><h1>等待,让脚本保持运行直到被中断</h1><p>wait "$SERVER_PID"
</p>
这样按下Ctrl+C后,服务器会被终止,锁文件被清除,终端状态恢复,整个过程可控且不留残局。










