trap命令用于捕获信号并执行自定义清理操作,支持int、term、exit、err等信号;需注意变量作用域、子shell生效条件及kill/stop信号不可捕获。

trap 命令用于在 Shell 脚本中定义当接收到特定信号(如 INT、TERM、EXIT)时要执行的清理或响应操作。它不改变信号默认行为本身,而是“捕获”并插入自定义逻辑。
基本语法和常用信号
格式为:trap 'command' SIGNAL_NAME 或 trap 'command' SIGNAL_NUMBER。
常见信号包括:
-
INT(2):用户按 Ctrl+C 触发 -
TERM(15):外部调用kill发送的终止请求(默认) -
EXIT(0):脚本即将退出时(无论成功或失败) -
ERR:任意命令返回非零状态(需开启set -o errtrace才能在函数中生效)
捕获 Ctrl+C 并安全退出
防止脚本被强制中断后留下临时文件或未关闭资源:
#!/bin/bash tmpfile="/tmp/myapp_$$" touch "$tmpfile" <p>trap 'rm -f "$tmpfile"; echo "Cleanup done, exiting..."; exit 1' INT</p><p>echo "Running... Press Ctrl+C to stop" while true; do sleep 1 done</p>
注意:$$ 是当前进程 PID,确保临时文件名唯一;exit 1 显式终止脚本,否则 trap 执行完会继续运行。
统一处理所有退出场景(含正常结束)
用 EXIT 捕获所有退出路径,适合通用清理:
#!/bin/bash log_file="/var/log/myscript.log" exec >> "$log_file" 2>&1 <p>trap 'echo "$(date): Script ended" >> "$log_file"' EXIT</p><p>echo "Script started at $(date)"</p><h1>... 主逻辑 ...</h1><p>sleep 2</p>
该 trap 在脚本自然结束、exit 被调用、或被信号中断(除非被其他 trap 覆盖)时都会触发。
清除或重置 trap
用空字符串清除某信号的 trap:trap '' INT;清除所有信号:trap -。
若想恢复默认行为(如让 Ctrl+C 真正中断脚本),可清除后再发送信号:
-
trap '' INT→ 后续 Ctrl+C 直接终止脚本 -
trap - INT→ 效果同上(-表示恢复默认) -
trap '' ERR→ 关闭错误捕获
注意事项
trap 中的变量需注意作用域:单引号内无法展开变量,应使用双引号并转义必要字符;若需在子 shell 中生效,需加 set -o errtrace(对 ERR)或显式用 export -f func_name 导出函数。
trap 不捕获 KILL(9)和 STOP(19/17/18)信号——它们无法被忽略或捕获。











