学而实习之 不亦乐乎

linux:kill命令详解

2020-08-19 19:29:09

kill命令用来中止一个进程。 
kill 可将指定的信号发送至程序。预设的信号为 SIGTERM(15),可将指定程序终止。若仍无法终止该程序,可使用 SIGKILL(9) 信息尝试强制删除程序。程序或工作的进程号(PID)可利用 ps 指令或 jobs 指令查看。

一、基本格式

语法
kill [ -s signal | -p ] [ -a ] pid ...
kill -l [ signal ]

参数
-l  显示信号,若果不加信号的编号参数,则使用“-l”参数会列出全部的信号名称
-a  当处理当前进程时,不限制命令名和进程号的对应关系
-p  指定kill 命令只打印相关进程的进程号,而不发送任何信号
-s  指定发送信号
-u  指定用户

说明
信号9(SIGKILL) 可以无条件终止进程,其他信号进程都可以忽略。 
下面是常用的信号:
HUP    1    终端断线
INT     2    中断(同 Ctrl + C)
QUIT    3    退出(同 Ctrl + \)
TERM   15    终止
KILL    9    强制终止
CONT   18    继续(与STOP相反, fg/bg命令)
STOP    19    暂停(同 Ctrl + Z)

注意
1、kill命令可以带信号号码选项,也可以不带。如果没有信号号码,kill命令就会发出终止信号(15),这个信号可以被进程捕获,使得进程在退出之前可以清理并释放资源。也可以用kill向进程发送特定的信号。例如:kill -2 123
它的效果等同于在前台运行PID为123的进程时按下Ctrl+C键。但是,普通用户只能使用不带signal参数的kill命令或最多使用-9信号。
2、kill可以带有进程ID号作为参数。当用kill向这些进程发送信号时,必须是这些进程的主人。如果试图撤销一个没有权限撤销的进程或撤销一个不存在的进程,就会得到一个错误信息。
3、可以向多个进程发信号或终止它们。
4、当kill成功地发送了信号后,shell会在屏幕上显示出进程的终止信息。有时这个信息不会马上显示,只有当按下Enter键使shell的命令提示符再次出现时,才会显示出来。
5、应注意,信号使进程强行终止,这常会带来一些副作用,如数据丢失或者终端无法恢复到正常状态。发送信号时必须小心,只有在万不得已时,才用kill信号(9),因为进程不能首先捕获它。要撤销所有的后台作业,可以输入 kill 0。因为有些在后台运行的命令会启动多个进程,跟踪并找到所有要杀掉的进程的PID是件很麻烦的事。这时,使用kill 0来终止所有由当前shell启动的进程,是个有效的方法。

二、kill 与进程

进程是Linux系统中一个非常重要的概念。Linux是一个多任务的操作系统,系统上经常同时运行着多个进程。我们不关心这些进程究竟是如何分配的,或者是内核如何管理分配时间片的,所关心的是如何去控制这些进程,让它们能够很好地为用户服务。 
Linux操作系统包括三种不同类型的进程,每种进程都有自己的特点和属性。
1.交互进程是由一个Shell启动的进程。交互进程既可以在前台运行,也可以在后台运行。
2.批处理进程和终端没有联系,是一个进程序列。
3.监控进程(也称系统守护进程)是Linux系统启动时启动的进程,并在后台运行。例如,httpd是著名的Apache服务器的监控进程。

kill命令的工作原理是,向Linux系统的内核发送一个系统操作信号和某个程序的进程标识号,然后系统内核就可以对进程标识号指定的进程进行操作。
比如在top命令中,我们看到系统运行许多进程,有时就需要使用kill中止某些进程来提高系统资源。在安装和登录时,系统多个虚拟控制台的作用是当一个程序出错造成系统死锁时,可以切换到其它虚拟控制台工作关闭这个程序。此时使用的命令就是kill,因为kill是大多数Shell内部命令可以直接调用的。 

三、应用实例 

1.列出所有信号名称
# kill -l

2.得到指定信号的数值
# kill -l KILL

3.强行中止一个进程标识号为324的进程: 
# kill -9 324

通常先用ps查找进程,然后用kill杀掉
# ps -ef|grep vim 
# kill 3268 

4.杀死指定用户所有进程
# kill -9 $(ps -ef | grep peidalinux)
# kill -u peidalinux

5.killall命令 
Linux下还提供了一个killall命令,可以直接使用进程的名字而不是进程标识号,与 kill 不同的是它会杀死指定名字的所有进程。kill 命令杀死指定进程 PID,需要配合 ps 使用,而 killall 直接对进程对名字进行操作,更加方便。例如:
# killall -HUP inetd