Trap
1. trap介绍⚓
trap命令是linux中用来在命令执行过程中捕获信号的。好像只能在脚本中使用???
trap [-lp] [[arg] sigspec ...]
当shell接收到了信号sigspec(可以是多个),就会执行arg命令。
- 若
arg不存在或者是-(但是为了区别于选项,会写成--),并且有至少一个指定的信号,那么就按照指定信号原来的动作行事(即清除指定信号的自定义动作)。 - 若
arg是空字符串,那么指定的sigspec会被忽视。 - 若
arg不存在且提供了选项-p,则显示与每个sigspec关联的trap命令。 - 若没有提供任何参数或只有选项
-p,那么打印和每个信号关联的命令列表。 -l选项使 shell 打印信号名称及其相应编号的列表。sigspec可以是信号号码或者信号名称(通过man 7 signal查看)。信号名称不区分大小写,SIG 前缀是可选的。
sigspec其它的值:
EXIT (0):表示从shell退出后执行arg命令。DEBUG:在每个 简单命令(for、变种for、case、select命令)和shell函数的第一条命令 执行之前执行arg命令。RETURN:每次执行完一个shell函数或脚本ERR:每当简单命令具有非零退出状态时,执行arg命令,同时也会执行EXIT的命令。如果失败的命令是以下情况则不会执行arg命令:- 是紧跟在
while或until关键字后面的命令列表的一部分; if语句中的test的一部分;- 在
&&或||命令列表中的一部分; - 命令的返回值通过
!反转。
- 是紧跟在
信号被忽略后,再进入shell时不会被捕获、重置或列出。创建未被忽略的捕获信号将重置为子shell或子shell环境中的原始值。
如果有任何sigspec是不合格的,那么trap命令的返回值是false,否则是true。
2. 常见信号⚓
参考:
https://www.jianshu.com/p/b26d4e520385
https://dsa.cs.tsinghua.edu.cn/oj/static/unix_signal.html
man 7 signal
| 信号 | 值 | 描述 |
|---|---|---|
| 1 | SIGHUP | 挂起进程,见下方详细解释 |
| 2 | SIGINT | 终止进程(打断进程???)Ctrl+C |
| 3 | SIGQUIT | 停止进程 |
| 9 | SIGKILL | 无条件终止进程 |
| 15 | SIGTERM | 尽可能终止进程 |
| 17 | SIGSTOP | 无条件停止进程,但不是终止进程 |
| 18 | SIGTSTP | 停止或暂停进程,但不终止进程 Ctrl+Z |
| 19 | SIGCONT | 继续运行停止的进程 |
- SIGHUP:控制终端被关闭时该信号会被发送到进程。最初被设计成通知挂起的过程。在现代操作系统中,该信号通常意味着伪终端或虚拟终端被关闭了。许多 daemons 会 reload 它们的配置文件和 reopen 他们的日志文件,而不是退出。
nohup可以让指令忽略该信号,与&搭配使用可让你在脱机状态下继续执行指令,参考在后台执行命令。
3. 举例⚓
当发生信号时忽略该信号
#!/bin/sh
trap "" 2
清除指定信号的指定动作,按原计划行事
#!/bin/sh
trap "" SIGINT
do something...
# 下面的代码不会再忽略SIGINT信号
trap -- SIGINT
do other something...
退出时执行命令
#!/bin/sh
# 即使中途打断程序(Ctrl+C)执行也会执行
trap "echo 'goodbye!'" 0
do something...