shell编程 信号处理

Posted 我的紫霞辣辣

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shell编程 信号处理相关的知识,希望对你有一定的参考价值。

信号控制

信号说明

在这里插入图片描述

HUP(1): 1、挂起信号 2、往往可以让进程重新加载配置
INT(2): 中断, 通常因为按下ctrl+c而产生的信号,用于通知前台进程组终止进程。
QUIT(3): 退出,和SIGINT类似, 但由QUIT字符(通常是Ctrl - \\ )来控制. 进程在因收到SIGQUIT退出时会产生core文件, 在这个意义上类似于一个程序错误信号。

TSTP(20): 停止进行运行,通常因为按下ctrl+z而产生的信号

KILL (9) 用来立即结束程序的运行. 本信号不能被阻塞、处理和忽略。如果管理员发现某个进程终止不了,可尝试发送这个信号。
TERM(15): 终止,是不带参数时kill默认发送的信号,默认是杀死进程,与SIGKILL不同的是该信号可以被阻塞和处理。通常用TERM信号来要求程序自己正常退出,如果进程终止不了,我们才会尝试SIGKILL。
ABRT(6): 中止, 通常因某些严重错误产生的引号

SIGCHLD

子进程结束时, 父进程会收到这个信号。

如果父进程没有处理这个信号,也没有等待(wait)子进程,子进程虽然终止,但是还会在内核进程表中占有表项,这时的子进程称为僵尸 进程。这种情
况我们应该避免(父进程或者忽略SIGCHILD信号,或者捕捉它,或者wait它派生的子进程,或者父进程先终止,这时子进程的终止自动由init进程来接管)。

查看信号的命令kill -l

注意:我们在使用信号的时候,不要加前缀SIG
例如:

kill -9 pid		或者   kill -s kill pid    		# 杀死进程
[root@m01 ftp]# 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. 下载并启动vsftpd服务
yum -y install vsftpd
cd /var/ftp/
echo 123 > a.txt
systemctl start vsftpd
[root@m01 ftp]# ps aux | grep [v]sftpd
root      17896  0.0  0.0  53292   576 ?        Ss   20:36   0:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf
  1. 使用IE浏览器查看vsftpd的数据

在这里插入图片描述

  1. 修改vsftpd配置文件,向操作系统发送hup信号,重新加载配置文件。
mkdir /test
echo 123 > /test/b.txt
[root@m01 ftp]# vim /etc/vsftpd/vsftpd.conf
anon_root=/test				# anon表示匿名用户访问

kill -1 17896				# 重新加载配置文件
[root@m01 ftp]# ps aux | grep [v]sftpd				# 进程的pid没有改变
root      17896  0.0  0.0  53292   776 ?        Ss   20:36   0:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf
nobody    17899  0.0  0.1  55416  1492 ?        Ss   20:36   0:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf
ftp       17901  0.0  0.1  55440  1080 ?        S    20:36   0:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf

注意 : 并不是所有的软件都支持信号。

在这里插入图片描述

信号处理

在脚本执行过程中, 可能会被一些键盘操作快捷方式所打断, 影响脚本运行。
我们在编写脚本的时候,可以捕捉默认的操作系统信号,可以自定义对捕捉到的信号进行处理,也可以忽略所捕捉到的信号。

案例一

vim a.sh
#!/bin/bash

echo $$				# 查看进程的pid
sleep 100

# 运行该脚本	
bash a.sh				# 此时kill -9 pid / ctrl + c / ctrl + \\ 都可以杀死该进程	
# 17941
# ^\\a.sh: line 4: 17942 Quit                    (core dumped) sleep 100

===========================================================================================================
vim a.sh
#!/bin/bash

# 捕捉到信号后打印"停止!!!",但是不影响信号的执行
trap "echo 停止!!!" INT
echo $$
sleep 100

# 运行该脚本
bash a.sh
# 17949
# ^C停止!!!		# 显示输出结果,进程结束

===========================================================================================================
vim a.sh
#!/bin/bash

# 注意,不可以捕捉kill信号。如果可以捕捉kill信号就变成流氓软件了哦!!!
trap "" INT QUIT TSTP HUP 
echo $$
sleep 100

# 执行脚本文件
bash a.sh
17978
# ^C^\\^Z		我们发现 ctrl + Z / ctrl + c / ctrl + \\ 都无法杀死进程
    
# 使用kill -9杀死进程    
kill -9 17978
#-bash: kill: (17978) - No such process

案例二

#!/bin/bash

trap "echo 已经识别到中断信号:ctrl+c" INT
trap 'echo 已经识别到中断信号:ctrl+\\\\' QUIT
trap 'echo 已经识别到中断信号:ctrl+z' TSTP

read -p "请输入你的名字: " name
echo "你的名字是:$name"

===========================================================================================================
[root@m01 ~]# bash m.sh 
请输入你的名字: ^C已经识别到中断信号:ctrl+c
^Z已经识别到中断信号:ctrl+z
^\\已经识别到中断信号:ctrl+\\
NANA
你的名字是:NANA                        

关于HUP信号

当用户注销(logout)或者网络断开或者终端关闭(注意注意注意,一定是终端整体关闭,不是单纯的exit)时,终端都会收到Linux HUP信号(hangup)信号,然后终端在结束前会关闭其所有子进程。

如果我们想让我们的进程在后台一直运行,不要因为用户注销(logout)或者网络断开或者终端关闭而一起被干掉,那么我们有两种解决方案

  • 方案1:让进程忽略Linux HUP信号
  • 方案2:让进程运行在新的会话里,从而成为不属于此终端的子进程,就不会在当前终端挂掉的情况下一起被带走。
方法1: 我们在当前会话窗口执行的进程,使用exit命令退出当前会话窗口。
那么在当前会话窗口起的子进程都会被pid为1的systemd(上帝进程)所接管。

方法2: nohup ping www.baidu.com &> /dev/null &		
nohup表示忽略hang up信号;结尾处的&表示在后台运行。子进程都会被pid为1的systemd(上帝进程)所接管。

方法3: setsid ping www.baidu.com &> /dev/null &
setsid提交的进程直接会被pid为1的systemd(上帝进程)所接管;结尾处的&表示在后台运行。

方法4: (ping www.baidu.com &> /dev/null &)
( &)提交的进程直接会被pid为1的systemd(上帝进程)所接管

方法5: 使用screen命令进行提交 
yum -y install screen
screen						# screen命令,创建一个新的会话窗口		
(ping www.baidu.com &> /dev/null &)			# 在新创建的screen窗口执行ping命令

以上是关于shell编程 信号处理的主要内容,如果未能解决你的问题,请参考以下文章

shell if 语句

常用python日期日志获取内容循环的代码片段

代码片段:Shell脚本实现重复执行和多进程

Linux bash基础特性二

Shell编程基础

VSCode自定义代码片段——JS中的面向对象编程