终止进程 kill 和 killall
终止进程 kill 和 killall
kill
一般情况下,终止一个前台进程使用 Ctrl + C
就可以了。对于一个后台进程就须用 kill
命令来终止。我们会先使用 ps
、top
等命令获得进程的 PID,然后使用 kill
命令来杀掉该进程。
实际上,kill
的功能是向进程发送信号的命令,而不仅仅是杀死进程。当然我们可以向进程发送一个终止运行的信号,此时的 kill
命令才是名至实归。事实上如果我们不给 kill
命令传递信号参数,它默认传递终止进程运行的信号给进程!
kill [options] <pid> [...]
-
<pid> […]
:把信号发送给列出的所有进程。 -
options
:-
-<signal>
:指定发送给进程的信号,指定信号的名称或号码都可以。 -
-l
:列出所有信号的名称和号码。
-
首先看 kill -l
, kill -l
可以看到所有可以发送给程序的信号
常用的信号:
代号 | 名称 | 内容 |
---|---|---|
1 | SIGHUP | 启动被终止的程序,可让该进程重新读取自己的配置文件,类似重新启动。 |
2 | SIGINT | 相当于用键盘输入 ctrl-c 来中断一个程序的进行。 |
9 | SIGKILL | 代表强制中断一个程序的进行,如果该程序进行到一半,那么尚未完成的部分可能会有“半产品”产生,类似 vim 会有 .filename.swp 保留下来。 |
15 | SIGTERM | 默认参数,以正常的方式来终止该程序。由于是正常的终止,所以后续的动作会将他完成,这样就可以清理并释放资源。比如 vim 程序,如果是正常的退出,就会删除掉临时文件 *.swp 。不过,如果该程序已经发生问题,就是无法使用正常的方法终止时,输入这个 signal 也是没有用的。 |
19 | SIGSTOP | 相当于用键盘输入 ctrl-z 来暂停一个程序的进行。 |
关于这个部分,请看《mktemp 命令和 trap 命令》的
trap 命令
小节
这些信号中只有第 9 种信号 (SIGKILL) 才可以无条件的终止进程,其他信号进程都有权利忽略。并且这么多的信号中常用的也不多,也就是 1、9、15,
首选 15,15 杀不掉,再用 9,不到万不得已,不要使用 9,会有很多问题。
kill <pid>
等价于 kill -15 <pid>
kill -9 <pid>
杀死用户(以 hnlinux 为例)的所有进程
//方法一 过滤出 hnlinux 用户进程
kill -9 $(ps -ef | grep hnlinux)
//方法二
kill -u hnlinux
注意:当用 kill
向这些进程发送信号时,必须是这些进程的主人。如果试图撤销一个没有权限撤销的进程或撤销一个不存在的进程,就会得到一个错误信息。
trap
用于在脚本中接收 kill
发送过来的信号。关于 trap
的解析,请看《mktemp 命令和 trap 命令》的 trap 命令
小节
killall
本质上,killall
跟 kill
命令一样,都是发送一条信号给指定的进程。
killall
用于杀死一个进程(kill processes by name),与 kill
不同的是它会杀死指定名字的所有进程。kill
命令杀死指定进程 PID,需要配合 ps
使用,而 killall
直接对进程对名字进行操作,更加方便。
killall
进程决不会杀死自己 (但是可以杀死其它 killall
进程)。
killall
杀死进程的时候会把进程的子进程也杀掉。
killall [选项] name
-
-Z
:只杀死拥有 scontext 的进程 -
-e
:要求进程需要和名字完全相符,进程名称即ps -ef
的command
或cmd
字段,默认 -
-I
:(i 的大写)忽略小写 -
-g
:杀死进程组而不是进程 -
-i
:交互模式,杀死进程前先询问用户 -
-l
:(L 的小写)列出所有的已知信号名称 -
-q
:不输出警告信息 -
-r
|--regexp
:将进程名模式解释为扩展的正则表达式。使用正则表达式,Blob 风格 -
-<signal>
发送指定的信号 -
-u
|--user
:结束指定用户的进程 -
-v
:报告信号是否成功发送 -
-w
:等待进程死亡 -
--help
:显示帮助信息 -
--version
:显示版本显示
常用参数就是 -r -<signal>
-u
保险一点,使用之前可以先用 ps -C <pro_name>
查看一下进程名称匹配到的进程,然后再用 killall <pro_name>
来杀,
这些信号中只有第 9 种信号 (SIGKILL) 才可以无条件的终止进程,其他信号进程都有权利忽略。并且这么多的信号中常用的也不多,也就是 1、9、15,
首选 15,15 杀不掉,再用 9,不到万不得已,不要使用 9,会有很多问题。
跟 kill
的信号一样,其实就相当于用 <pro_name>
代替了 <pid>
killall <pro_name>
等价于 killall -15 <pro_name>
killall -9 <pro_name>
pkill
跟 killall
类似,
pkill [选项] name
这里就不研究了。
最佳实践
以 sshd
服务为例,Linux 上的 sshd
服务,是 SSH 链接服务,这个服务开机自启,监控 22 端口,然后 xshell 之类的客户端才可以通过访问 Linux 服务器的 22 端口建立 SSH 链接,
可以很明显的看到,sshd pid 是 9324,这是 sshd 服务,然后开启两个子进程,22233 和 23963,这是两个 ssh 链接,对应着我在 xshell 中开启的两个 tab,都是用 lk 登录上去的。然后这两个进程又各自开启了子进程。
kill 9324
普通用户执行此命令,9324 不会被杀,提示不允许的操作,带 -9 也不行,root 用户执行此命令会杀掉,杀掉后,sshd 服务关闭,无法再新建 ssh 连接。但是已经建立的 ssh 连接不会关闭。
killall sshd
普通用户执行此命令,sshd 服务进程不会被杀,但是所有的 ssh 链接都将关闭,因为进程名称 sshd 匹配上了这些进程,root 用户执行此命令,sshd 服务和所有 sshd 连接都会被杀
重启 sshd 服务(需要管理员权限):systemctl start sshd
说明,sshd 服务需要管理员权限才可以操作
在 Xshell 中新建连接,就是多了一个 ssh 进程,杀掉对应用户的 ssh 进程,就是踢掉这个用户,不让其登录。
在虚拟机中打开虚拟机桌面,打开一个终端,就是打开一个 bash 进程,想要杀掉一个 bash 的进程,kill <bash_pid>
是无效的,需要 kill -9 <bash_pid>