为shell布置陷阱:trap捕捉信号方法论

1.2 trap布置陷阱

1.3 布置完美陷阱必备知识

家里有老鼠,快消灭它!哎,又给跑了。老鼠这小东西跑那么快,想直接直接消灭它还真不那么容易。于是,老鼠药、老鼠夹子或老鼠笼就派上用场了,它们都是陷阱,放在那静静地等待着老鼠的光顾。

在shell中,也可以捉"老鼠",捉到"老鼠"后,可以无视它、杀死它或者抓起来逗一番。只需使用内置命令trap(中文就翻译为陷阱、圈套)就可以布置一个陷阱,这个陷阱当然不是捕老鼠的,而是捕捉信号。

通常trap都在脚本中使用,主要有2种功能:

(1).忽略信号。当运行中的脚本进程接收到某信号时(例如误按了CTRL+C),可以将其忽略,免得脚本执行到一半就被终止。

(2).捕捉到信号后做相应处理。主要是清理一些脚本创建的临时文件,然后退出。

1.1 信号说明

详细的信号说明见:信号。常见的信号以及它们的数值代号、说明如下:

Signal Value Comment ───────────────────────────── SIGHUP 1 终止进程,特别是终端退出时,此终端内的进程都将被终止 SIGINT 2 中断进程,几乎等同于sigterm,会尽可能的释放执行clean-up,释放资源,保存状态等(CTRL+C) SIGQUIT 3 从键盘发出杀死(终止)进程的信号 SIGKILL 9 强制杀死进程,该信号不可被捕捉和忽略,进程收到该信号后不会执行任何clean-up行为,所以资源不会释放,状态不会保存 SIGTERM 15 杀死(终止)进程,几乎等同于sigint信号,会尽可能的释放执行clean-up,释放资源,保存状态等 SIGSTOP 19 该信号是不可被捕捉和忽略的进程停止信息,收到信号后会进入stopped状态 SIGTSTP 20 该信号是可被忽略的进程停止信号(CTRL+Z)

每个信号其真实名称并非是SIGXXX,而是去除SIG后的单词,每个信号还有其对应的数值代号,在使用信号时,可以使用这3种方式中的任一一种。例如SIGHUP,它的信号名称为HUP,数值代号为1,发送HUP信号时,以下3种方式均可。

kill -1 PID kill -HUP PID kill -SIGHUP PID

在上面所列的信号列表中,KILL和STOP这两个信号无法被捕捉。一般来说,在设置信号陷阱时,只会考虑HUP、INT、QUIT、TERM这4个会终止、中断进程的信号。

1.2 trap布置陷阱

trap的语法格式为:

1. trap [-lp] 2. trap cmd-body signal_list 3. trap '' signal_list 4. trap signal_list 5. trap - signale_list 语法说明: 语法1:-l选项用于列出当前系统支持的信号列表,和"kill -l"一样的作用。 -p选项用于列出当前shell环境下已经布置好的陷阱。 语法2:当捕捉到给定的信号列表中的某个信号时,就执行此处给定cmd-body中的命令。 语法3:命令参数为空字符串,这时shell进程和shell进程内的子进程都会忽略信号列表中的信号。 语法4:省略命令参数,重置陷阱为启动shell时的陷阱。不建议此语法,当给定多个信号时结果会出人意料。 语法5:等价于语法4。 trap不接任何参数和选项时,默认为"-p"

(1).查看当前shell已布置的陷阱。

[root@linuxidc ~]# trap trap -- '' SIGTSTP trap -- '' SIGTTIN trap -- '' SIGTTOU

这3个陷阱都是信号忽略陷阱,当捕获到TSTP、TTIN或TTOU信号时,将不做任何处理。

(2).设置一个可以忽略CTRL+C和15信号的陷阱。

[root@linuxidc ~]# trap '' SIGINT SIGTERM [root@linuxidc ~]# trap trap -- '' SIGINT trap -- '' SIGTERM trap -- '' SIGTSTP trap -- '' SIGTTIN trap -- '' SIGTTOU

这样一来,当前的shell就无法被kill -15杀死。

[root@linuxidc ~]# kill $BASHPID;echo kill current bash failed kill current bash failed

(3).设置一个陷阱,当这个陷阱捕捉到15信号时,就打印一条消息。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/13539.html