千家信息网

shell脚本中如何进行信号的捕捉

发表于:2025-02-02 作者:千家信息网编辑
千家信息网最后更新 2025年02月02日,本篇文章给大家分享的是有关shell脚本中如何进行信号的捕捉,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。trap从字面意思看就是就是陷
千家信息网最后更新 2025年02月02日shell脚本中如何进行信号的捕捉

本篇文章给大家分享的是有关shell脚本中如何进行信号的捕捉,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

trap从字面意思看就是就是陷阱的意思但是在shell脚本中trap时专门捕捉kill -9,kill -15,CTRL+C等信号的。

1、查看所有可用的信号

trap -l或kill -l即可

[root@linux1 ~]# kill -l63) SIGRTMAX-1  64) SIGRTMAX    [root@linux1 ~]# trap -l 1) SIGHUP   2) SIGINT   3) SIGQUIT  4) SIGILL   5) SIGTRAP 6) SIGABRT  7) SIGBUS   8) SIGFPE   9) SIGKILL 10) SIGUSR111) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM......

2、常见的信号如下:

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后的单词,每个信号还有对应的代号

比如向PID为12345的进程发起1信号

kill -1 12345kill -HUB 12345kill -SIGHUB 12345

3、trap的选项

trap -l列出当前系统支持的信号列表,上面已经使用过,根kill -l一样

trap -p等价于trap,查看shell已经布置好的陷阱

可以看到shell默认有三个陷阱,表示忽略20,21,22信号

[root@linux1 ~]# traptrap -- '' SIGTSTPtrap -- '' SIGTTINtrap -- '' SIGTTOU

4、陷阱捕捉到信号后干嘛

  • 忽略信号

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

5、设置一个可以忽略CTRL+C和15信号的陷阱

CTRL信号对应的是SIGINT 15信号对应的是SIGTERM

[root@linux1 ~]# trap '' SIGINT SIGTERM[root@linux1 ~]# traptrap -- '' SIGINTtrap -- '' SIGTERMtrap -- '' SIGTSTPtrap -- '' SIGTTINtrap -- '' SIGTTOU

这样,当前shell就不能被kill -15杀死

6、设置一个陷阱,捕捉到-15信号时,就打印"我抓到你啦~"

[root@linux1 ~]# trap 'echo "我抓到你啦~"' TERM[root@linux1 ~]# traptrap -- '' SIGINTtrap -- 'echo "我抓到你啦~"' SIGTERMtrap -- '' SIGTSTPtrap -- '' SIGTTINtrap -- '' SIGTTOU

效果,当我对当前bash发起kill -15信号时就打印出来了

[root@linux1 ~]# echo $$8827[root@linux1 ~]# kill -15 8827我抓到你啦~[root@linux1 ~]# kill -15 8827我抓到你啦~[root@linux1 ~]# kill -15 8827我抓到你啦~

7、在脚本中设置一个能忽略CTRL+C和CTRL+Z信号的脚本

CTRL+C是2信号,即SIGINT

CTRL+Z是20信号,即SIGTSTP

脚本:

脚本沉睡10s,然后打印success,脚本忽略INT和TSTP信号

[root@linux1 ~]# cat trap.sh#!/bin/bashtrap '' SIGINT SIGTSTPsleep 10echo success

效果:

CTRL+C也不能阻止我睡觉

[root@linux1 ~]# bash trap.sh ^C^C^Z^Z^C^C^Z^Zccc^Z^Z^Z^C^C^Csuccess

8、布置一个当脚本被终端时能清理垃圾并立即退出脚本的陷阱

脚本如下:

[root@linux1 ~]# cat trap1.sh#!/bin/bashtrap 'echo trap handing...;rm -rf /tmp/$BASHPID;echo TEMP files cleaned;exit' SIGINT SIGTERM SIGQUIT SIGHUPmkdir -p /tmp/$$/touch /tmp/$$/{a..c}.txtsleep 10echo first sleep successsleep 10echo second sleep success

这样,脚本除了SIGKILL信号(kill -9),总能清理掉临时垃圾

效果

刚开始一直不能终止,后来执行了下trap发现前面shell自己设置了一个忽略CTRL+C的陷阱,退出shell重进即可

[root@linux1 ~]# bash trap1.sh ^Ctrap handing...TEMP files cleaned

9、陷阱的守护对象

陷阱的守护对象是shell进程本身,不会守护shell环境内的子进程。但如果是信号忽略型陷阱,则会守护整个shell进程组使其忽略给定信号。

[root@linux1 ~]# cat trap2.sh #!/bin/bashtrap 'echo trap_handle_time: $(date +"%F %T")' SIGINT SIGTERMecho time_start: $(date +"%F %T")sleep 10echo time_end1: $(date +"%F %T")sleep 10echo time_end2: $(date +"%F %T")#执行脚本后,新开终端使用kill -15杀死它[root@linux1 ~]# killall -s SIGTERM trap2.sh#查看输出情况[root@linux1 ~]# ./trap2.sh time_start: 2019-08-27 10:43:48trap_handle_time: 2019-08-27 10:43:58time_end1: 2019-08-27 10:43:58time_end2: 2019-08-27 10:44:08

可以发现,kill执行完后,屏幕没有立即打印trap_handle,而是等sleep 10运行完后才打印的。sleep进程都被忽略型trap守护了

只要是向shell进程发送的信号,都会等待当前正在运行的命令结束后才处理信号,然后继续脚本向下运行。(实际上,只有当shell脚本中正在执行的操作是信号安全的系统调用时,才会出现信号无法中断进程的情况,而在shell下的各种命令,我们是没法直接知道哪些命令中正在执行的系统调用是系统调用的)。

但sleep命令发起的sleep()调用,是一个信号安全的,所以上面脚本中执行sleep的过程中,信号不会直接中断它们的运行,而是等待它运行完之后再执行信号处理命令。

10、如果shell中针对某信号设置了陷阱,则该shell进程接收到该信号时,会等待其内正在运行的命令结束才开始处理陷阱

11、CTRL+C和SIGINT不是等价的。当某一时刻按下CTRL+C,它是在向整个当前运行的进程组发送SIGINT信号。对shell脚本来说,SIGINT不仅发送给shell脚本进程,还发送给脚本中当前正在运行的进程

[root@linux1 ~]# cat trap2.sh #!/bin/bashtrap 'echo trap_handle_time: $(date +"%F %T")' SIGINT SIGTERMecho time_start: $(date +"%F %T")sleep 10echo time_end1: $(date +"%F %T")sleep 10echo time_end2: $(date +"%F %T")#执行脚本后,立马CTRL+C[root@linux1 ~]# bash trap2.sh time_start: 2019-08-27 10:20:53^Ctrap_handle_time: 2019-08-27 10:20:54time_end1: 2019-08-27 10:20:54time_end2: 2019-08-27 10:21:04

可以发现,CTRL+C后,不仅trap进行处理了,sleep也立马结束了;说明CTRL+C不仅让脚本进程收到了SIGINT信号,也让当前进程收到了SIGINT信号

以上就是shell脚本中如何进行信号的捕捉,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注行业资讯频道。

信号 脚本 进程 陷阱 运行 命令 正在 处理 状态 系统 终端 就是 效果 而是 资源 安全 垃圾 对象 尽可能 情况 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 数据库原理及应用期末考试题库 虚拟机作服务器给物理机分配网段 在服务器上能查到吗 网络技术学平面设计吗 拯救者数据库系统概论期末试题 网络安全业务怎么盈利 闵行区常规网络技术服务质量保障 西安公安局网络安全 开源图像数据库 超威24槽服务器内存怎么插 卡兹克网络技术有限公司 database数据库 无锡软件开发服务外包 用友服务器可以用自己的电脑吗 医院网络安全员文件 聚信联合网络技术服务 中国移动互联网科技中心在哪里 幻塔vivo渠道服服务器 大学专业软件开发 龙神契约服务器 中文的数据库类型 2003服务器系统不能分盘 吉林大学本科生毕业论文数据库 东华软件开发人员好跳槽吗 网络安全社区医院用吗 免费海外服务器ip地址pptp 廊坊国家网络安全宣传周 qq游戏大厅服务器异常断开链接 ibm服务器远程管理工具 专业化软件开发包括
0