linux下进程追捕者之”trap“

Linux中运行着大量的进程,而研究并处理好进程之间的关系,对排查问题,编写脚本十分有用。Linux的追踪命令则为我们提供了这样的工具,犹如《黑客帝国》中,在一座进程组成的城市中,如何感知到某个进程的异常,如何去搜寻,抓捕一个非法的进程,如何处理进程等等。今天就来初探一下这个有趣的话题(笔者能力有限,如有疏漏,欢迎大佬指出)。

一:进程是如何产生的

linux下存在两种命令,内建命令与外部命令(非内建命令)
外部命令,可以理解为系统的“干儿子”。当外部命令执行时,会创建出一个子进程,这个子进程才有资格到”爷爷“内核那里,用来运行外部命令程序,这种操作被称为衍生。对于内建命令就是”亲儿子“了,直接在shell进程运行,不需要创建子进程进行运行命令。
”亲儿子“内建命令必然是少数,详细请看这里。而大部分外部命令执行时,比如sleep都得通过内核中的folk-exec函数,产生子进程,放入LINUX内核进行了一系列操作:
1、shell父进程(PID=X)调用fork()系统调用创建了一个子进程(PID=Y,PPID=X)。
2、父进程X调用wait()系统调用一直等待子进程Y结束。
3、同时,子进程Y调用exec()系统调用执行命令,执行完成后,调用exit()系统调用结束生命。
4、父进程的wait()收到信息,释放子进程PCB,彻底销毁子进程Y。
linux下进程追捕者之”trap“
如图这里的sleep,ps都在父进程bash下执行

注意:
1.在子shell中定义的变量只在该子shell内有效。子进程或其他进程之间是无效的。如果在一个shell脚本程序中定义了一个变量,当该脚本程序运行时,这个定义的变量只是该脚本程序内的一个局部变量,其他的shell不能引用它。
2.export命令将使系统在创建每一个新的shell时定义这个变量的一个拷贝。这个过程称之为变量输出。

二:追寻进程间的信号处理

信号是在软件层次上对中断机制的一种模拟,原理上一个进程收到一个信号与处理器收到一个中断请求是一样的。信号事件的来源:硬件来源(比如按下键盘或其他 硬件故障)、软件来源(比如系统函数kill、raise、alarm、setitimer和sigqueue函数)。信号是进程间通信机制中唯一的异步通信机制。
常用的进程信号:
HUP(1)    挂起,通常因终端掉线或用户退出而引发
INT(2)    中断,通常因按下Ctrl+C组合键而引发
QUIT(3)  退出,通常因按下Ctrl+组合键而引发
ABRT(6)  中止,通常因某些严重的执行错误而引发
ALRM(14)  报警,通常用来处理超时
TERM(15)  终止,通常在系统关机时发送

shell向进程发送信号大多通过Ctrl键加上一些功能键来实现。除了利用组合键发送信号外,内建命令kill可用于向进程发送TERM(即terminal)信号,功能和INT信号类似用于停止进程。kill可以通过进程号、作业号(kill %n)或进程命令名想任何作业发送信号。关于全部的信号
详细请点这里

三.进程捕获之:trap命令

使用场景:
第一种: trap “commands” signal-list(信号列表)
当脚本收到signal-list清单内列出的信号时,trap命令执行双引号中的命令.
linux下进程追捕者之”trap“
第二种:
trap signal-list
trap不指定任何命令,接受信号的默认操作.默认操作是结束进程的运行.

第三种:
trap ’ ’ signal-list
trap命令指定一个空命令串,允许忽视信号.如图 对INT,TERM忽略而对HUP执行
linux下进程追捕者之”trap“
linux下进程追捕者之”trap“
注意:
1.针对同一种信号的trap捕获最后一条
2.若在内建命令执行时,收到信号,其实是在执行完毕后再发出做出XX操作
3.部分的信号并无法捕捉,比如SIGKILL,SIGSTOP以及段错误类
linux下进程追捕者之”trap“
linux下进程追捕者之”trap“
kill -9 执行后并未触发执行ByeBye
4. EIXT信号可以捕获,可作为程序退出时的一些必要操作十分有用
linux下进程追捕者之”trap“
linux下进程追捕者之”trap“