信号
一、信号的类型
[root@wh 531]# kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
二、常见信号的介绍以及举例验证
1) SIGHUP hangups -->挂起(结束一个会话)
本信号在用户终端连接(正常或非正常)结束时发出, 通常是在终端的控制进程结束时, 通知同一session内的各个作业, 这时它们与控制终端不再关联。登录Linux时,系统会分配给登录用户一个终端(Session)。在这个终端运行的所有程序,包括前台进程组和后台进程组,一般都属于这个 Session。当用户退出Linux登录时,前台进程组和后台有对终端输出的进程将会收到SIGHUP信号。这个信号的默认操作为终止进程,因此前台进 程组和后台有终端输出的进程就会中止。不过可以捕获这个信号,比如wget能捕获SIGHUP信号,并忽略它,这样就算退出了Linux登录,wget也 能继续下载。 nohup可以忽略sighup信号
此外,对于与终端脱离关系的守护进程,这个信号用于通知它重新读取配置文件。
2) SIGINT(Ctrl+C)
程序终止(interrupt)信号, 在用户键入INTR字符(通常是Ctrl-C)时发出,用于通知前台进程组终止进程。3) SIGQUIT
和SIGINT类似, 但由QUIT字符(通常是Ctrl-)来控制. 进程在因收到SIGQUIT退出时会产生core文件, 在这个意义上类似于一个程序错误信号。9) SIGKILL
用来立即结束程序的运行. 本信号不能被阻塞、处理和忽略。如果管理员发现某个进程终止不了,可尝试发送这个信号。15) SIGTERM(默认)
程序结束(terminate)信号, 与SIGKILL不同的是该信号可以被阻塞和处理。通常用来要求程序自己正常退出,shell命令kill缺省产生这个信号。如果进程终止不了,我们才会尝试SIGKILL。
1) SIGHUP(结束一个会话)
#第一个终端
[root@wh 531]# cat while.sh
#!/bin/bash
i=1
while :
do
echo $i
((i++))
sleep 1
done
[root@wh 531]# bash while.sh
1
2
3
4
#第二个终端
[root@wh 531]# ps aux|grep while
root 14039 0.0 0.0 113284 1408 pts/0 S+ 09:57 0:00 bash while.sh
root 14047 0.0 0.0 112824 988 pts/1 S+ 09:57 0:00 grep --color=auto while
#×掉第一个终端,相当于结束第一个会话,传递的是1这种信号,可以结束进程,在第二个终端看效果
[root@wh 531]# ps aux|grep while
root 14056 0.0 0.0 112824 988 pts/1 S+ 09:57 0:00 grep --color=auto while
那能不能忽略1这种信号呢?
[root@wh 531]# cat while.sh
#!/bin/bash
i=1
while :
do
echo $i
((i++))
sleep 1
done
#nohup忽略传递的sighup信号,这样的话就算结束会话,程序也会继续运行
[root@wh 531]# nohup bash while.sh
nohup: 忽略输入并把输出追加到"nohup.out"
#×掉这个会话,在另一个会话看效果
[root@wh 531]# ps aux|grep while
root 14092 0.0 0.0 113284 1412 ? S 10:01 0:00 bash while.sh
root 14116 0.0 0.0 112824 988 pts/1 S+ 10:01 0:00 grep --color=auto while
[root@wh 531]# kill -9 14092
#输出的信息保存到了当前文件中的nohup.out
[root@wh 531]# ls
nohup.out trap.sh while.sh
[root@wh 531]# cat nohup.out
1
2
3
4
5
...
23
#把程序放在后台运行
[root@wh 531]# nohup bash while.sh &
[1] 14152
[root@wh 531]# nohup: 忽略输入并把输出追加到"nohup.out"
#×掉这个会话,在另一个终端看效果,发现×掉会话,程序也还在运行
[root@wh 531]# ps aux|grep while
root 14152 0.0 0.0 113284 1408 ? S 10:08 0:00 bash while.sh
root 14190 0.0 0.0 112824 988 pts/1 S+ 10:09 0:00 grep --color=auto while
[root@wh 531]# kill -9 14152
[root@wh 531]# ps aux|grep while
root 14199 0.0 0.0 112824 988 pts/1 S+ 10:09 0:00 grep --color=auto while
#总结
nohup可以忽略传递的1这种信号,以后在工作中,如果说在运行程序,如果突然断电,会话会终止,那么程序会停止运行,这个时候nohup就起到了作用,如果使用nohup信号,会话被终止,程序也能继续运行,并将运行结果保存。
2) SIGINT(Ctrl+C) 15) SIGTERM(默认)的介绍
#第一个终端
[root@wh 531]# cat while.sh
#!/bin/bash
i=1
while :
do
echo $i
((i++))
sleep 1
done
[root@wh 531]# bash while.sh
1
2
3
#另一个终端
[root@wh 531]# ps aux|grep while
root 13937 0.0 0.0 113284 1412 pts/0 S+ 09:35 0:00 bash while.sh
root 13952 0.0 0.0 112824 988 pts/1 S+ 09:36 0:00 grep --color=auto while
#kill 不接信号类型 默认是15号信号,SIGTERM
[root@wh 531]# kill 13937
#15号和2号信号都可以终止进程
[root@wh 531]# bash while.sh
1
2
3
4
5
6
7
已终止
# Ctrl+C 是2号信号
[root@wh 531]# bash while.sh
1
2
3
4
^C
使用trap将信号捕捉
[root@wh 531]# cat while.sh
#!/bin/bash
trap "echo i am busy" 15 2
i=1
while :
do
echo $i
((i++))
sleep 1
done
[root@wh 531]# bash while.sh
1
2
3
4
5
#另一个终端
[root@wh 531]# ps aux|grep while
root 13972 0.0 0.0 113284 1444 pts/0 S+ 09:42 0:00 bash while.sh
root 13978 0.0 0.0 112824 988 pts/1 S+ 09:42 0:00 grep --color=auto while
[root@wh 531]# kill 13972
[root@wh 531]# kill -9 13972
[root@wh 531]# bash while.sh
1
2
3
4
5
6
7
8
9
10
11
i am busy #捕捉到15号信号,输出规定的内容
12
13
14
15
^Ci am busy #捕捉到2号信号,输出规定的内容
16
17
18
19
20
21
22
23
24
25
已杀死 #使用kill -9 强制杀死进程
那9号信号可以被捕捉到吗?
不能,9这种信号既不能被捕捉,也不能被忽略
[root@wh 531]# cat while.sh
#!/bin/bash
trap "echo i am busy" 15 2 9
i=1
while :
do
echo $i
((i++))
sleep 1
done
[root@wh 531]# bash while.sh
1
2
3
4
[root@wh 531]# ps aux |grep while
root 14002 0.0 0.0 113284 1448 pts/1 S+ 09:46 0:00 bash while.sh
root 14027 0.0 0.0 112824 984 pts/0 S+ 09:46 0:00 grep --color=auto while
[root@wh 531]# kill -9 14002
[root@wh 531]# bash while.sh
1
2
3
4
5
6
7
8
9
10
已杀死