终止进程 kill 和 killall
终止进程 kill 和 killall
kill
一般情况下,终止一个前台进程使用 Ctrl + C
就可以了。对于一个后台进程就须用 kill
命令来终止。我们会先使用 ps
、top
等命令获得进程的 PID,然后使用 kill
命令来杀掉该进程。
实际上,kill
的功能是向进程发送信号的命令,而不仅仅是杀死进程。当然我们可以向进程发送一个终止运行的信号,此时的 kill
命令才是名至实归。事实上如果我们不给 kill
命令传递信号参数,它默认传递终止进程运行的信号给进程!
|
|
-
<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
杀死进程的时候会把进程的子进程也杀掉。
|
|
-
-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
类似,
|
|
这里就不研究了。
最佳实践
以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>