我使用过的Linux命令之trap
我使用过的Linux命令之trap详细介绍
在 Linux 中,trap 命令是 Shell 脚本中用于捕获、处理或忽略信号(Signal)的重要工具。它可以让脚本在接收到特定信号时执行自定义的操作(如清理临时文件、保存状态、提示信息等),从而增强脚本的健壮性和可控性。以下是关于 trap 的详细用法和示例:
一、基本语法
bash
命令或函数 信号列表
- 命令或函数:接收到信号时执行的操作(可以是单行命令、函数名或空字符串)。
- 信号列表:可以是信号名称(如
SIGINT)或编号(如2),多个信号用空格分隔。
二、常用信号
通过 trap -l 可查看所有信号,以下是常见信号:
| 信号名称 | 编号 | 说明 | 触发场景 |
|---|---|---|---|
SIGINT |
2 | 中断信号(Ctrl+C) | 用户主动终止脚本 |
SIGTERM |
15 | 终止信号(默认 kill 命令发送) | 系统或其他程序终止脚本 |
SIGQUIT |
3 | 退出信号(Ctrl+\) | 用户强制退出 |
SIGKILL |
9 | 强制终止信号(不可捕获 / 忽略) | 用 kill -9 发送 |
EXIT |
- | 脚本退出时触发(非传统信号) | 脚本正常结束或提前退出 |
ERR |
- | 命令执行失败时触发(Bash 4.1+) | 某条命令返回非零状态码 |
三、核心用法
1.
捕获信号并执行自定义操作
最常见的场景是在脚本接收到中断信号(如 SIGINT)时,清理临时文件或输出提示信息。
bash
脚本接收到中断信号,正在清理临时文件..."
/tmp/temp_file.txt
cleanup SIGINT SIGTERM
- 当用户按下
Ctrl+C或通过kill <进程号>终止脚本时,会先执行cleanup函数,再退出。
2.
处理脚本退出(EXIT 信号)
无论脚本以何种方式结束(正常退出、收到信号、错误终止),EXIT 信号都会触发,常用于资源释放:
bash
EXIT
3.
忽略特定信号
通过为空字符串绑定信号,使脚本忽略该信号:
bash
SIGINTSIGQUIT
4.
恢复信号默认行为
通过 - 或空参数恢复信号的默认处理方式:
bash
- SIGINT
5.
在函数中使用 trap(作用域)
trap 的作用域仅限于当前 Shell 环境:
- 在函数内部设置的
trap,仅在函数执行期间生效(除非使用export或在全局作用域设置)。 - 在子 Shell(如
(...)或fork产生的进程)中,trap不会继承父 Shell 的设置。
四、示例:复杂场景应用
场景:监控脚本运行,捕获错误并记录日志
bash
ERR
+ '脚本结束'" EXIT
'; exit 1" SIGINT
"
五、注意事项
- 信号处理的时机:
- 信号处理程序会在 Shell 从异步事件(如信号)恢复后立即执行,而非在信号触发的瞬间(可能存在微小延迟)。
- 引号的使用:
- 处理命令需用双引号(
"")包裹,以便 Shell 解析变量和命令替换(如$LINENO、$(date))。
- 处理命令需用双引号(
- 不可捕获的信号:
SIGKILL(9)和SIGSTOP(19)无法被捕获或忽略,用于强制终止 / 暂停进程。
- 子进程的继承:
- 子进程(如通过
&后台运行的命令)不会继承父进程的trap设置,需单独定义。
- 子进程(如通过
总结
trap 是 Shell 脚本中处理异常终止、资源清理和流程控制的关键工具。通过合理使用,可以让脚本更健壮,避免临时文件残留、数据不一致等问题。重点掌握 SIGINT、SIGTERM 和 EXIT 信号的处理,结合自定义函数,能显著提升脚本的可靠性。