15.LINUX命令kill
15.LINUX命令kill
1.kill命令简介
在Linux统中,kill命令用于向运行中的进程发送信号,默认发送的信号是终止信号,会请求进程退出。kill(杀)可能会引起误解,实际上发送的信号可能与杀死进程无关。
我们最常使用到的kill命令为:
kill PID
kill -9 PID
前者为请求目标进程退出,后者为强制杀死目标进程。
1.1kill PID
kill命令默认发送的信号是SIGTERM。该信号会被目标进程捕获,在收到这个信号以后目标进程可以做一些有用的操作(如保存数据),然后退出。然而,许多进程并没有专门实现处理此信号的程序,此时会调用默认的信号处理函数。而在某些情况下,有特殊处理程序的进程也会出错,无法正确处理信号。总之,SIGTERM信号不能确保目标进程能够退出。
SIGTERM信号的编号通常为15,可通过以下四种方式发送SIGTERM信号:
kill PID
kill -s TERM PID
kill -TERM PID
kill -15 PID
1.2 kill -9 PID
此时发送的是SIGKILL信号。正如前文所述,SIGTERM信号不一定能够“杀死”目标进程,在这种情况下,我们就会释放大杀器,SKGKILL信号。SIGKILL信号不会被进程所“截获”,它只能由主机系统内核处理,由其负责提供可靠的控制进程执行的方法,SIGKILL会杀死进程。
SIGKILL信号的编号通常为9,可通过三种方式发送SIGKILL信号:
kill -s KILL PID
kill -KILL PID
kill -9 PID
1.3其他kill信号
kill命令可以发送的信号还有很多,其它有用的信号包括HUP、TRAP、INT、SEGV及ALRM等。
HUP发送SIGHUP信号,SIGHUP信号的意思为挂起。在规范上,进程应当在收到这个信号时重新加载配置,相当于重启。但在实际使用中,通常只有守护进程会按照规范实施,而普通进程则是执行退出。
INT发送SIGINT信号,意为中断,在终端中,只需按下CTRL+C便可以产生SIGINT信号。
在终端中,CTRL+Z通常映射至SIGTSTP,CTRL+\(反斜杠)映射至SIGQUIT,这可强制程序进行核心转储。
2.kill能确保杀死进程吗?
答案是否定的,某些情况下即使kill -9也无法杀死进程。
2.1用户授权
UNIX提供了安全机制,以防止未授权用户杀死其他进程。实际上,若进程欲向另一个进程发送信号,发送信号的进程的所有者必须与接收信号的进程的所有者相同,或者发送信号的进程的所有者是超级用户root。
例如,假设当前终端的用户是dancen,则无法kill掉用户nginx启动的进程。
2.2超级进程
即使root用户也无法向PID为1的进程发送信号。内核初始化的最后一步就是启动init进程。这个进程是系统的第一个进程,PID为1,又叫超级进程,也叫根进程。它负责产生其他所有用户进程。所有的进程都会被挂在这个进程下,如果这个进程退出了,那么所有的进程都被kill。如果一个子进程的父进程退了,那么这个子进程会被挂到PID 1下面,即PPID为1。
2.3内核态进程
当一个进程执行系统调用而陷入内核代码中执行时,该进程由用户态转为内核态,处于内核态的进程将忽略所有信号处理。如果进程在执行系统调用时无限期地阻塞,则可能无法终止该进程。
2.4僵尸进程
进程停止后,该进程就会从进程列表中移除。但是,有时候有些进程即使执行完了也依然留在进程列表中。这些完成了生命周期但却依然留在进程列表中的进程,我们称之为 “僵尸进程”。
a. 僵尸进程的产生
一个进程可能会产生很多子进程。这些子进程执行完毕后会发送一个Exit信号然后死掉。这个Exit信号需要被父进程所读取。父进程随后调用wait命令来读取子进程的退出状态,并将子进程从进程列表中移除。但若父进程未能读取到子进程的Exit信号,则这个子进程不会从进程列表中删掉。
b. 找出僵尸进程
ps aux | grep Z
c. kill僵尸进程
我们可以分别通过SIGTERM信号、SIGKILL信号、SIGHUP信号来尝试kill僵尸进程。
kill PID
kill -9 PID
kill -HUP PID
如果僵尸进程没能kill掉,则可查看僵尸进程的PPID,找到父进程,令其回收子进程;如果无效,则可直接kill掉僵尸进程的父进程,父进程死后,僵尸进程成为”孤儿进程”,过继给1号进程init,由init负责清理僵尸进程。
方法一,传递信号给父进程,命令其回收子进程的资源
kill -CHLD PPID
方法二,直接kill父进程,将此进程变成孤儿进程,交给init进程管理,由init进程回收此进程的资源
kill -9 PPID
2.5自我保护的进程
最后这一种情况是我在阿里云的服务器上遇到的。
我在执行硬盘扩展时,需要将硬盘卸载,但在执行umount命令时,提示设备忙。
a. 找出正在使用设备的进
# fuser -mv /mnt/volume1/
USER PID ACCESS COMMAND
/mnt/volume1: root kernel mount /mnt/volume1
root 10516 f.... AliYunDun
结果显示名为AliYunDun的进程占用了设备。
b. kill AliYunDun进程1
# kill 10516
bash: kill: (10516) - Operation not permitted
# kill -9 10516
bash: kill: (10516) - Operation not permitted
# sudo kill -9 10516
kill: sending signal to 10516 failed: Operation not permitted
AliYunDun是阿里云安全中心的客户端代理,为了防止被恶意kill,具有自我保护功能,我在kill该进程时,提示没有权限,并且收到了阿里云的告警:
c. kill AliYunDun进程2
暂时不知道AliYunDun自我保护功能的实现原理,但该进程可以通过 HUP信号kill掉。
kill -HUP 1051
d. 补充资料
卸载阿里云安全中心Agent官方文档:
参考资料: