Linux下Shell信号发送与捕捉

1、Linux信号类型

信号(Signal):信号是在软件层次上对中断机制的一种模拟,通过给一个进程发送信号,执行相应的处理函数。

进程可以通过三种方式来响应一个信号:

1)忽略信号,即对信号不做任何处理,其中有两个信号不能忽略:SIGKILL及SIGSTOP。

2)捕捉信号。

3)执行缺省操作,Linux对每种信号都规定了默认操作。

Linux究竟采用上述三种方式的哪一个来响应信号呢?取决于传递给响应的API函数。

Linux支持的信号有:

编号信号名称缺省动作描述
1SIGHUP终止终止进程,挂起
2SIGINT终止键盘输入中断命令,一般是CTRL+C
3SIGQUITCoreDump键盘输入退出命令,一般是CTRL+\
4SIGILLCoreDump非法指令
5SIGTRAPCoreDumptrap指令发出,一般调试用
6SIGABRTCoreDumpabort(3)发出的终止信号
7SIGBUSCoreDump非法地址
8SIGFPECoreDump浮点数异常
9SIGKILL终止立即停止进程,不能捕获,不能忽略
10SIGUSR1终止用户自定义信号1,像Nginx就支持USR1信号,用于重载配置,重新打开日志
11SIGSEGVCoreDump无效内存引用
12SIGUSR2终止用户自定义信号2
13SIGPIPE终止管道不能访问
14SIGALRM终止时钟信号,alrm(2)发出的终止信号
15SIGTERM终止终止信号,进程会先关闭正在运行的任务或打开的文件再终止,有时候有的进程在运行任务会忽略此信号。不能捕捉
16SIGSTKFLT终止处理器栈错误
17SIGCHLD可忽略子进程结束时,父进程收到的信号
18SIGCONT可忽略让终止的进程继续执行
19SIGSTOP停止停止进程,不能忽略,不能捕获
20SIGSTP停止停止进程,一般是CTRL+Z
21SIGTTIN停止后台进程从终端读数据
22SIGTTOU停止后台进程从终端写数据
23SIGURG可忽略紧急数组是否到达socket
24SIGXCPUCoreDump超出CPU占用资源限制
25SIGXFSZCoreDump超出文件大小资源限制
26SIGVTALRM终止虚拟时钟信号,类似于SIGALRM,但计算的是进程占用的时间
27SIGPROF终止类似与SIGALRM,但计算的是进程占用CPU的时间
28SIGWINCH可忽略窗口大小改变发出的信号
29SIGIO终止文件描述符准备就绪,可以输入/输出操作了
30SIGPWR终止电源失败
31SIGSYSCoreDump非法系统调用

CoreDump(核心转储):当程序运行过程中异常退出时,内核把当前程序在内存状况存储在一个core文件中,以便调试。执行命令ulimit -c如果是0则没有开启,也不会生成core dump文件,可通过ulimit -c unlimited命令临时开启core dump功能,只对当前终端环境有效,如果想永久生效,可修改/etc/security/limites.conf文件,添加一行 “* soft core unlimited”

默认生成的core文件保存在可执行文件所在的目录下,文件名为core。如果想修改core文件保存路径,可通过修改内核参数:echo “/tmp/corefile-%e-%p-%t” > /proc/sys/kernel/core_pattern 则文件名格式为core-命名名-pid-时间戳

Linux支持两种信号:

一种是标准信号,编号1-31,称为非可靠信号(非实时),不支持队列,信号可能会丢失,比如发送多次相同的信号,进程只能收到一次,如果第一个信号没有处理完,第二个信号将会丢弃。

另一种是扩展信号,编号32-64,称为可靠信号(实时),支持队列,发多少次进程就可以收到多少次。

信号类型比较多,我们只要了解下,记住几个常用信号就行了,红色标记的我觉得需要记下。

发送信号一般有两种情况:

一种是内核检测到系统事件,比如键盘输入CTRL+C会发送SIGINT信号。

另一种是通过系统调用kill命令来向一个进程发送信号。

2、kill命令

kill命令发送信号给进程。
命令格式:kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... 

kill -l [sigspec]
-s  # 信号名称
-n  # 信号编号
-l  # 打印编号1-31信号名称

示例:
给一个进程发送终止信号:
[root@ chenc01 ~]# kill -s SIGTERM pid[root@ chenc01 ~]# kill -n 15 pid[root@ chenc01 ~]# kill -15 pid[root@ chenc01 ~]# kill -TREM pid

3、trap命令

trap命令定义shell脚本在运行时根据接收的信号做相应的处理。
命令格式:trap [-lp] [[arg] signal_spec ...]

-l      # 打印编号1-64编号信号名称
arg     # 捕获信号后执行的命令或者函数
signal_spec # 信号名或编号

一般捕捉信号后,做以下几个动作:
1)清除临时文件
2)忽略该信号
3)询问用户是否终止脚本执行

示例1:按CTRL+C不退出循环
#!/bin/bash
trap "" 2   # 不指定arg就不做任何操作,后面也可以写多个信号,以空格分隔 
for i in {1..10}; do
  echo $i
  sleep 1
done

[root@ chenc01 ~]# bash a.sh
1
2
3
^C4
5
6
^C7
8
9
10

示例2:循环打印数字,按CTRL+C退出,并打印退出提示

#!/bin/bash
trap "echo 'exit...';exit" 2
for i in {1..10}; do
  echo $i
  sleep 1
done
[root@ chenc01 ~]# bash test.sh
1
2
3
^Cexit...

示例3:让用户选择是否终止循环

#!/bin/bash
trap "func" 2
func() {
  read -p "Terminate the process? (Y/N): " input
  if [ $input == "Y" ]; then
     exit
  fi
}
for i in {1..10}; do
  echo $i
  sleep 1
done
[root@ chenc01 ~]# bash a.sh
1
2
3
^CTerminate the process? (Y/N): Y
[root@ chenc01 ~]# bash a.sh 
1
2
3
^CTerminate the process? (Y/N): N
4
5
6
...
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值