shell中的信号捕获trap(shell 进阶)

本文介绍了Shell脚本中的trap命令,用于在接收到特定信号时执行指定操作,如清理临时文件和后台进程。通过示例展示了如何设置trap来捕获INT、HUP、QUIT和TERM信号,并讨论了交互式shell对这些信号的处理方式。同时,文中提到了一些使用trap时的注意事项和常见陷阱,如信号守护的范围和信号发送的区别。
摘要由CSDN通过智能技术生成

 

目录

trap的基础概念 

定义一个trap 

 忽略信号 

 重置信号

 trap的实例

清理临时文件

清理脚本中的后台进程

采坑点

快捷键:CTRL+(C、Z、\):对于脱离了终端的后台进程无效

接收到信号后,会等待正在执行的前台任务完成后去触发信号处理程序。原因是:shell认为前台进程都是重要任务

 信号守护的范围

CTRL+C和SIGINT不等价:前者发INT给shell及其内所有子进程,后者只发送给shell

交互式shell默认会自动忽略TERM信号。在任何情况下,都会忽略QUIT信号


trap的基础概念 

定义一个trap 

[root@15:14:15 /opt/shellTest]#trap -p
[root@15:14:17 /opt/shellTest]#
[root@15:14:18 /opt/shellTest]#
[root@15:14:18 /opt/shellTest]#trap 'echo traped' INT
[root@15:18:06 /opt/shellTest]#
[root@15:18:07 /opt/shellTest]#
[root@15:18:07 /opt/shellTest]#trap -p
trap -- 'echo traped' SIGINT

这个意思就是说当按下Ctrl +c 时输出 traped 

可以以列表的形式去定义

 忽略信号 

忽略TERM信号

 忽略INT信号

 重置信号

 trap的实例

清理临时文件

经常在脚本中会创建文件然后执行结束之后删除,但是当脚本在删除前发生异常,则就会有临时文件产生。如何解决这个问题呢?

捕获异常并触发删除脚本达到此目的。

#!/bin/bash
trap 'echo traped;rm -rf $tmp_dir;exit 1' INT HUP QUIT TERM

tmp_dir=/tmp/$BASHPID
mkdir -p $tmp_dir
touch $tmp_dir/{a..d}.log
echo "$tmp_dir"
ls -l $tmp_dir
sleep 5s


rm -rf $tmp_dir

echo "over"

注意可以使用trap 'echo traped;rm -rf $tmp_dir;exit 1' EXIT

但是不推荐,因为需要程序员去考虑EXIT是哪种退出,而INT HUP QUIT TERM是明确的退出信号。

一般trap的action中要exit 1. 这个是退出状态码,可以自己定义并作出相应的动作,例如报警...

清理脚本中的后台进程

当脚本脱离终端运行后,即使你发送INT信号,还是会一直输出。

看一个小例子

#!/bin/bash

while true;do
sleep 1s
echo hhahha
done & 
sleep 3

 主进程等待3s之后,将while true进行后台运行。即使发送INT信号也没有用。使用killall bash才可以停下。

此处需要注意一定要取消刚才定义的trap TERM才能生效。

 

#!/bin/bash
  
function signal_hangdle {
        echo trapped
        kill $pid
        exit 1
}

#trap  'signal_handle' EXIT

sleep 10s &
pid=$!

sleep 20s &
pid="$! $pid"


sleep 5s
~                                                                               
~               

结果: 

 使用trap INT的结果:

 trap EXIT:

问题点: 脚本中需要不断收集进程id,如果有10个sleep那就需要收集后台进程ID。

man一下kill 的用法 0 代表进程组,那直接kill 0就可以免去收集后台进程ID

 

结果:

 

采坑点

快捷键:CTRL+(C、Z、\):对于脱离了终端的后台进程无效

接收到信号后,会等待正在执行的前台任务完成后去触发信号处理程序。原因是:shell认为前台进程都是重要任务

 信号守护的范围

CTRL+C和SIGINT不等价:前者发INT给shell及其内所有子进程,后者只发送给shell

 

交互式shell默认会自动忽略TERM信号。在任何情况下,都会忽略QUIT信号

killall bash也是基于此才不会关闭当前终端这个shell

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MyySophia

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值