|
1、Linux信号类型 信号(Signal):信号是在软件层次上对中断机制的一种模拟,通过给一个进程发送信号,执行相应的处理函数。 进程可以通过三种方式来响应一个信号: 1)忽略信号,即对信号不做任何处理,其中有两个信号不能忽略:SIGKILL及SIGSTOP。 2)捕捉信号。 3)执行缺省操作,Linux对每种信号都规定了默认操作。 Linux究竟采用上述三种方式的哪一个来响应信号呢?取决于传递给响应的API函数。 Linux支持的信号有: 编号 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 用户自定义信号1,像Nginx就支持USR1信号,用于重载配置,重新打开日志 | | | | | | | | | | | | | | | | | | | | 终止信号,进程会先关闭正在运行的任务或打开的文件再终止,有时间进程在有运行的任务而忽略此信号。不能捕捉 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 虚拟时钟信号,类似于SIGALRM,但计算的是进程占用的时间 | | | | 类似与SIGALRM,但计算的是进程占用CPU的时间 | | | | | | | | | | | | | | | | |
CoreDump(核心转储):当程序运行过程中异常退出时,内核把当前程序在内存状况存储在一个core文件中,以便调试。
% h6 ^+ A2 D* n- E
Linux支持两种信号: 一种是标准信号,编号1-31,称为非可靠信号(非实时),不支持队列,信号可能会丢失,比如发送多次相同的信号,进程只能收到一次,如果第一个信号没有处理完,第二个信号将会丢弃。 另一种是扩展信号,编号32-64,称为可靠信号(实时),支持队列,发多少次进程就可以收到多少次。 信号类型比较多,我们只要了解下,记住几个常用信号就行了,红色标记的我觉得需要记下。
$ y- X$ l9 d1 h0 @/ A0 ?
发送信号一般有两种情况: 一种是内核检测到系统事件,比如键盘输入CTRL+C会发送SIGINT信号。 另一种是通过系统调用kill命令来向一个进程发送信号。 2、kill命令kill命令发送信号给进程。 命令格式:kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... kill -l [sigspec] -s # 信号名称 -n # 信号编号 -l # 打印编号1-31信号名称 示例:
7 |5 W) ~1 g+ }: X: ?1 U, o. Y- 给一个进程发送终止信号:8 K6 [# f& O7 |0 @
- kill -s SIGTERM pid
6 g) f* S2 {, u1 g( `: Q( j - 或, o5 S# ]' P. m! T1 J& M
- kill -n 15 pid
( ^1 w4 Y8 ]5 t - 或7 d+ ]6 {* V+ ?: h: n
- kill -15 pid P# a' T: x2 ?* ~, \7 q
- 或
/ }( M4 o2 N2 X& h: |* ] - kill -TREM pid
复制代码
& i, x: p) `. v4 Y& u 3、trap命令trap命令定义shell脚本在运行时根据接收的信号做相应的处理。 命令格式:trap [-lp] [[arg] signal_spec ...] -l #打印编号1-64编号信号名称 arg # 捕获信号后执行的命令或者函数 signal_spec # 信号名或编号 一般捕捉信号后,做以下几个动作: 1)清除临时文件 2)忽略该信号 3)询问用户是否终止脚本执行 示例1:按CTRL+C不退出循环
4 T- T e* y$ X+ J- #!/bin/bash' M( [# [; d8 ]8 {0 [* Y$ R! [
- trap "" 2 # 不指定arg就不做任何操作,后面也可以写多个信号,以空格分隔 ' s. n* [1 R/ n( Y
- for i in {1..10}; do
% C' Z% _& G$ k {' s- W - echo $i
7 g7 n D' p+ p! R3 V; h7 l; g n - sleep 1: G% |$ k# f- M/ o
- done
( f F# L' h# O) y& L6 | - # bash a.sh4 w3 w T! Z: D U
- 1
/ ?9 d B% U0 I. C* r Y- t - 2 O& `+ n/ f% @+ D" ?
- 3
7 `4 H% h; [. W$ O! {" ?% H( J& | - ^C4
+ A" N0 d, x. B3 v9 h$ E - 5
$ H4 a. a1 o2 _/ r6 M' D - 6& A4 z! f7 l$ N
- ^C7
& O9 k2 X" p2 P$ p - 86 f. J5 b; u( H6 B( K0 Y
- 9
& u1 ?/ M, A$ O; I/ L2 Z - 10
复制代码 8 H6 h* v7 L0 X9 E- r' h
' {" Z; x# `) a: O5 ^6 e1 p! T
示例2:循环打印数字,按CTRL+C退出,并打印退出提示
t8 X" ]3 m7 z8 K" X( a" z) r- #!/bin/bash( \5 L% c& ^* ?6 W1 J/ J
- trap "echo 'exit...';exit" 27 C* `8 S7 j* e0 z7 i) E _' H7 J
- for i in {1..10}; do" c) F. G6 D5 Q3 j
- echo $i- X! e. G# B+ v/ x1 q& a
- sleep 1
4 @+ k0 q; M% W& `2 H) x) N: L3 S - done _* g, u, a9 u7 `$ @! L* P, R
- # bash test.sh5 x7 a4 I& W) {. ^' D" s
- 1
6 g! R! D e9 j - 26 y' Y+ R7 |; }* F2 V& C
- 3; O7 s" `' h) E0 I
- ^Cexit...
复制代码
6 S6 [: l' c+ V; z C4 |
示例3:让用户选择是否终止循环 - ) {$ k/ ^2 p( ^3 E" i) Y
- #!/bin/bash
: b% i9 f2 _. R: h5 l - trap "func" 2! u3 v5 Q2 b1 h
- func() {
' F# s, N0 O" A# \# L( Y - read -p "Terminate theprocess? (Y/N): " input9 j" q$ g8 v& C5 w' `9 h
- if [ $input == "Y"] ; then8 I$ F& s4 |3 U; U" L
- exit
$ J) p( {7 ^1 P& ^. p2 R - fi
8 n2 A0 p) m* ^ - } 0 F' x! B6 k7 G/ u" Q4 w! l
- for i in {1..10}; do4 u& ?" D4 k, n" ?
- echo $i
3 ^: J& `- L2 |$ S - sleep 1- `5 Y( x# i+ K5 w& C
- done
; T, Z3 z, s+ i/ c3 i - 2 P; k5 ~; h7 Y- D# B
- # bash a.sh
: a7 W# k9 x* S( K3 U( c - 1( ] ^* U1 ~/ P/ f, ~
- 25 l, _) ~" Y' q; Y8 h* N P: F
- 3% n7 q9 c4 w7 V& h$ N5 W0 V! R8 @0 `
- ^CTerminate the process? (Y/N): Y6 W& ~* l2 J V0 c
- # bash a.sh : ^( z5 i" U0 J
- 13 z N% Z) i: n: Y) n
- 2
$ A( u. ]$ [+ o' E - 32 `- u8 Q! u0 T- I) N- r, }- r
- ^CTerminate the process? (Y/N): N' `0 ~3 p+ l* G; C3 V
- 4
- l9 s$ y, k. S - 5
( l& W! P) P5 L - 6; d$ A7 @3 W2 L$ L
- ...
复制代码
' v6 J; G/ _5 t* M$ x8 u3 d5 F* l' t |