其他分享
首页 > 其他分享> > kill、killall发送信号命令

kill、killall发送信号命令

作者:互联网

kill 命令,一眼看上去就让人觉得是"杀掉"的含义,但其实kill命令是用来发送信号的,我们先来看一下信号的种类。

信号的种类

信号:即一个进程发送给另一个进程的消息。
Linux系统中有十几种信号,每一种信号都被分配了一个数字和一个名字。常用的信号如下:
kill -l 或 trap -l #查看系统中全部的信号命令

[root@Centos8 shell_scripy]# 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

可以看到信号的种类有很多,我们最关注的是信号9和信息号15,9表示无条件终止,15表示终止指定进程;

kill命令

kill命令可以发送各种信号给某个进程,不要因为kill的名字就认为它只能杀死进程。

kill命令格式:kill [ -s sigspec | -n signum | -sigapec ][ pid | jobspec]

说明:通过sigspec或 signum指定要发送的信号,sigspec既可以是任意大小写信号的名字(有无SIG前缀都可以),也可以是给信号分配的数字,而signum只能是数字。pid为进程的进程号。(可用ps -fC 进程名或jobs -l,来查看进程的PID)
kill命令会把指定的信号发送给进程号为pid的进程或者发送给作业号为jobspec的进程。如果没有给kill命令指定任何信号,kill命令就默认发送SIGTERM信号,收到SIGTERM命令的进程就会结束运行,这就是普通情况下使用kill命令杀死进程的过程,再次提醒:不要因为kill的名字就认为它只能杀死进程,实际上kill命令可以发送各种信号给某个进程。
示例:杀死PID为4269的后台进程:
①kill -n 15 4211 #指定信号的数字号为15并发送给PID为4211的进程
②kill -s HUP 4269 或 kill-s sighup 4269 或 kill -n 1 4269 #3者是等价的
③kill 4215 #不指定信号,则发送默认的SIGTERM信号
有时候我们执行一个脚本时可能会产生很多临时文件,当然我们可以在脚本的最后面写命令来删除这些不需要的临时文件,但当我们的脚本程序执行中间被Ctrl+c或kill的时候,因为可能程序已经产生了临时文件但在执行删除命令前就被终止了,所以此时临时文件并没有被删除。这时我们就可以用信号这种机制来自动解决这个问题。即需要在脚本中自定义一个收到这些终止信号时执行具体操作的回调函数。
trap命令语法:trap commands signal1 signal2 signal3…
说明:其中commands 可以是一系列的命令或一个函数名,在它的后面是一系列信号的数字或信号名,这些信号的任意一个发送到shell脚本,或者说这些信号的任意一个被脚本所捕获时,所指定的命令或函数就会被执行。
其实,trap的commands 命令可以被省略,当没有指定commands 命令时,shell脚本接收到这些信号时就会执行它们的默认值,每一个信号都有一个默认值。
注意:当shell脚本进程接收到一个信号时,它会暂停当前的工作并查看是哪一个信号,然后检查信号是否被忽略,如果没有被忽略就执行commands 命令,如果没有commands 命令就执行信号的默认行为,当执行完commands 命令相关的操作后,如果没有exit退出脚本的命令,则它就返回到收到信号的地方继续执行下一条指令。所以,如果需要在接收到信号时就退出,就需要在commands 命令中写一条exit命令。
虽然在kill-l或trap -l中找不到信号0这个信号,但这个信号时存在的,它是一个伪信号,对应于exit (无论exit后面是否有数字);也就是说,当程序执行到最后末尾程序即将退出或遇到exit即将退出时,就会触发伪信号0。利用这个特性,我们可以在脚本执行完毕时做一些善后懂得工作。如 trap show_goodbey 0。
屏蔽信号:当进程不想被中途某个信号打断时,我们可以指定trap操作为空或:来屏蔽这个信号的默认操作,(:号是bash的一个内建命令,它总是说明也不做并且返回0,因此用来表示一个空操作再合适不过了)如:trap ‘’1 15或trap :1 15
注意:依个人理解,信号的捕获应该是从接收到信号的地方其向上搜索,搜到相应的信号对应的trap命令后执行,所以如果此时前面还有n条对相同的信号处理的trap命令,则都不会被执行,只执行向上搜索找到的第一条相应的信号的trap命令,如果在接收到信号的地方下面也有相同信号的trap命令,也不会被执行。

注意:建议使用-15信号,因为这样父进程及其子进程都会释放资源后才终止,而9信息直接杀死进程太野蛮,可能会造成父进程被杀死了其子进程还在,这样造成了僵尸进程的存在,而僵尸进程会被1号进程托管。

演示示例:

使用9信号杀掉进程:
[root@Centos8 ~]# ps -ef | grep nginx		#查看nginx的进程号PID
root        2705       1  0 12:59 ?        00:00:00 nginx: master process nginx
nginx       2706    2705  0 12:59 ?        00:00:00 nginx: worker process
root        2708    1769  0 12:59 pts/0    00:00:00 grep --color=auto nginx

[root@Centos8 ~]# kill -9 2705
[root@Centos8 ~]# ps -ef | grep nginx		#发现存在nginx的work进程,存在了僵尸进程,同时work进程因为其父进程死了会被1号进程托管了
nginx       2706       1  0 12:59 ?        00:00:00 nginx: worker process
root        2721    1769  0 13:00 pts/0    00:00:00 grep --color=auto nginx

[root@Centos8 ~]# kill  -9 2706			#继续干掉work进程
[root@Centos8 ~]# ps -ef | grep nginx		#这样nginx进程已经全部都被干掉了
root        2773    1769  0 13:03 pts/0    00:00:00 grep --color=auto nginx

使用15信号杀掉进程:
[root@Centos8 ~]# nginx
[root@Centos8 ~]# ps -ef | grep nginx
root        2864       1  0 13:10 ?        00:00:00 nginx: master process nginx
nginx       2865    2864  0 13:10 ?        00:00:00 nginx: worker process
root        2867    1769  0 13:10 pts/0    00:00:00 grep --color=auto nginx
[root@Centos8 ~]# kill -15 2864		#使用15信号杀掉master进程,全部的进程包括其子进程都被杀掉了
[root@Centos8 ~]# ps -ef | grep nginx
root        2869    1769  0 13:10 pts/0    00:00:00 grep --color=auto nginx

killall命令

如果我们已经知道我们想要杀死的那个进程的名字,我们能够利用 killall 命令发送同样的信号,那么该进程的所有父进程子进程都会收到信息,像这样:

[root@Centos8 ~]# nginx
[root@Centos8 ~]# ps -ef | grep nginx
root        2897       1  0 13:13 ?        00:00:00 nginx: master process nginx
nginx       2898    2897  0 13:13 ?        00:00:00 nginx: worker process
root        2900    1769  0 13:13 pts/0    00:00:00 grep --color=auto nginx
[root@Centos8 ~]# killall -15 nginx		#使用killall直接指定进程名称即可
[root@Centos8 ~]# ps -ef | grep nginx
root        2903    1769  0 13:13 pts/0    00:00:00 grep --color=auto nginx

标签:00,killall,发送,nginx,kill,信号,进程,root
来源: https://blog.csdn.net/MssGuo/article/details/117174036