linux信号
一、现象描述:
1.当运行shell脚本时,如果按下Ctrl+c 或Ctrl+x(x为其他字符),程序会终止运行。
2.当不希望shell在运行时被终止,则可以使用屏蔽信号手段,让程序忽略用户输入的信号指令,从而继续运行shell程序。
二、信号含义:
信号是由一个整数构成的异步消息,它可以由某个进程发给其他进程,也可以在用户按下特定按键发生某种异常事件时,由系统发给某个进程。
1.Linux重要信号
kill -l
HUP(1) 挂起,通常因终端掉线或用户退出而引发
INT(2) 中断,通常因为按ctrl + c组合键而引发
QUIT(3) 退出,通常因为按ctrl + 组合键而引发
ABRT(6) 中止 , 通常因为某些严重的执行错误而引发
KILL(9) 杀死 , 强制杀死
ALRM(14) 报警 , 通常用来处理超时
TERM(15) 终止 ,通常在系统关机时发送,正常退出
TSTP(20) 停止进程的运行,但该信号可以被处理和忽略,通常是Ctrl + z键而引发
注:
shell脚本中可以用数字来代表信号,也可以用信号的名字代表信号,也可以用组合键代表信号
不是所有的信号都能被trap捕捉(比如 kill -9),trap只能捕捉常见的信号
收到信号的是进程、所有进程
终端也可以叫做会话
父进程死亡,子进程将会成为孤儿进程,被systemd进程(pid=1)收留(父进程被杀)
关闭终端,发送HUP信号,systemd包括其子进程被中断
2.trap命令
trap命令:
1.用于在接受到信号后将要采取的行动
2.常用于在脚本程序被中断时完成清理工作,或者屏蔽用户非法使用的某些信号
注:
使用信号名时需要省略前缀"SIG"
用法:
trap command signal
signal是接受到的信号 , command是接收到信号后应该采取的行动
trap "命令;命令" 信号名 或者 trap "命令;命令" 信号编号
例一:
处理单个信号:
[centos@mycentos ~]$ trap "" 2 #若执行动作为空,则可以用来屏蔽与数字对应的Ctrl+c信号
[centos@mycentos ~]$ trap ":" 2 #此处恢复Ctrl + c 的信号
[centos@mycentos ~]$ ^C #已恢复
例二:
同时处理多个信号:
[centos@mycentos ~]$ trap "" 1 2 3 20 #<==执行这些数字信号,什么都不做,即屏蔽这些信号
[centos@mycentos ~]$ trap ":" 1 2 3 20 #<==执行这些信号,恢复对应的功能
[centos@mycentos ~]$ ^C
[centos@mycentos ~]$ trap "" HUP INT QUIT TSTP #<==执行这些名称信号,什么都不做,即屏蔽这些信号
[centos@mycentos ~]$ trap ":" HUP INT QUIT TSTP #<==执行这些名称信号,恢复对应的功能
[centos@mycentos ~]$ ^C
[centos@mycentos ~]$ trap "" `echo {1..64}` #<==屏蔽1-64所有的数字信号
实战一:
开发脚本实现触发信号后清理文件功能(信号触发后就会执行将新建的文件删除命令)
#!/bin/bash
#Auther:itboy
#Time:2018-11-20 10:09:42
#Name:3.sh
#Version:V1.0
#Description:this is a test script.
#<==捕获ctrl+c 键后即执行find删除命令,后退出脚本
trap "find /tmp -type f -name "old_*" | xargs rm -f && exit" INT
while true
do
touch /tmp/old_$(date +%F-%T) #<==在/tmp创建文件
sleep 5 #<==休息3秒
ls -la /tmp/old* #<==查看文件创建情况
done
实战二:
开发脚本,练习QUIT、TSTP、INT
#!/bin/sh
#捕获ctrl+c信号时,执行echo命令
trap 'echo "you are typing ctrl-c ,sorry,script will not terminate"' INT
#捕获Ctrl+信号,执行echo
trap 'echo "you are typing ctrl- ,sorry,script will not terminate"' QUIT
#捕获ctrl+z信号,就会执行echo命令 (实测此处没有执行echo命令,进程异常)
trap 'echo "you are typing ctrl-z ,sorry,script will not terminate"' TSTP
while true
do
echo "now , test signal $(date)"
sleep 5
done
效果如下
[root@mycentos ~]# sh 2.sh
now , test signal Tue Nov 20 11:02:06 CST 2018
^Cyou are typing ctrl-c ,sorry,script will not terminate #按下ctrl+c执行
now , test signal Tue Nov 20 11:02:11 CST 2018
now , test signal Tue Nov 20 11:02:16 CST 2018
now , test signal Tue Nov 20 11:02:21 CST 2018
^Quit (core dumped)
you are typing ctrl- ,sorry,script will not terminate #按下ctrl+执行
now , test signal Tue Nov 20 11:02:25 CST 2018
now , test signal Tue Nov 20 11:02:30 CST 2018
^Z^Z #按下ctrl +z 键没有打印提示,但是程序停止运行了
实战三
实现红绿灯
#!/bin/bash
trap "" INT QUIT HUP TERM TSTP
clear
n=0
while :
do
[ $n -eq 0 ] && n=1 || n=0
if [ $n -eq 1 ];then
echo -e " 33[31m 红灯亮 33[0m"
else
echo -e " 33[32m 绿灯亮 33[0m"
fi
sleep 0.5
clear
done
实现红黄绿
#!/bin/bash
#trap "" INT QUIT HUP TERM TSTP
clear
while :
do
for i in 0 1 2
do
case $i in
0)
echo -e " 33[31m 红灯亮 33[0m"
;;
1)
echo -e " 33[33m 黄灯亮 33[0m"
;;
2)
echo -e " 33[32m 绿灯亮 33[0m"
esac
sleep 0.5
clear
done
done
进程脱离当前终端
一父进程
父进程自杀
[root@hass-11 ~]# tty
/dev/pts/3
[root@hass-11 ~]# sh 1.sh &
[root@hass-11 ~]# ps -ef|grep 1.sh
root 92154 79953 0 10:44 pts/0 00:00:00 sh 1.sh
root 92221 79953 0 10:44 pts/0 00:00:00 grep --color=auto 1.sh
[root@hass-11 ~]# kill 79953
[root@hass-11 ~]# ps -ef|grep 1.sh
root 92154 79953 0 10:44 pts/0 00:00:00 sh 1.sh
root 92260 79953 0 10:45 pts/0 00:00:00 grep --color=auto 1.sh
[root@hass-11 ~]# kill -9 79953
重新连接该终端,发现进程退出
#该命令的过程有两个
1.父进程自杀
2.子进程被杀
父进程被杀
#窗口1
[root@hass-11 ~]# tty
/dev/pts/3
[root@hass-11 ~]# sh 1.sh &
[root@hass-11 ~]# ps -ef|grep 1.sh
root 92427 92356 0 10:46 pts/0 00:00:00 sh 1.sh
root 92472 92356 0 10:46 pts/0 00:00:00 grep --color=auto 1.sh
[root@hass-11 ~]# echo $$
92356
#窗口2
[root@hass-11 ~]# tty
/dev/pts/1
[root@hass-11 ~]# ps -ef|grep 1.sh
root 92427 92356 0 10:46 pts/0 00:00:00 sh 1.sh
root 92558 89686 0 10:47 pts/1 00:00:00 grep --color=auto 1.sh
[root@hass-11 ~]# kill -9 92356
[root@hass-11 ~]# ps -ef|grep 1.sh #杀死父进程,子进程在该终端继续存活
root 92427 1 0 10:46 ? 00:00:00 sh 1.sh
root 92596 89686 0 10:47 pts/1 00:00:00 grep --color=auto 1.sh
#此方法可以让进程脱离终端限制
#该方法原理与nohup一样
二nohup
#窗口1
[root@hass-11 ~]# echo $$ #查看当前进程的PID
98947
[root@hass-11 ~]# nohup ping www.baidu.com &
[1] 114856
[root@hass-11 ~]# ps -ef|grep [p]ing
root 114856 98947 0 13:37 pts/2 00:00:00 ping www.baidu.com
[root@hass-11 ~]# exit
#窗口2
[root@hass-11 ~]# echo $$
89686
[root@hass-11 ~]# ps -ef|grep [p]ing
root 114856 1 0 13:37 ? 00:00:00 ping www.baidu.com
#nohup的原理是,使要运行的进程的父进程是systemd
三setsid
#窗口1
[root@hass-11 ~]# setsid ping www.baidu.com &
[root@hass-11 ~]# exit
#窗口2
[root@hass-11 ~]# ps -ef|grep [p]ing
root 115312 1 0 13:40 ? 00:00:00 ping www.baidu.com
#setsid的原理是,使要运行的进程的父进程是systemd
四 ( &)
#窗口1
[root@hass-11 ~]# (ping www.baidu.com &) #必须加 & 符号
[root@hass-11 ~]# exit
#窗口2
[root@hass-11 ~]# ps -ef|grep [p]ing
root 115794 1 0 13:44 ? 00:00:00 ping www.baidu.com
#原理是开启一个子进程,使要运行的进程的父进程是systemd