终止进程 kill 和 killall

警告
本文最后更新于 2023-10-24,文中内容可能已过时。

终止进程 kill 和 killall

kill

一般情况下,终止一个前台进程使用 Ctrl + C 就可以了。对于一个后台进程就须用 kill 命令来终止。我们会先使用 pstop 等命令获得进程的 PID,然后使用 kill 命令来杀掉该进程。

实际上,kill 的功能是向进程发送信号的命令,而不仅仅是杀死进程。当然我们可以向进程发送一个终止运行的信号,此时的 kill 命令才是名至实归。事实上如果我们不给 kill 命令传递信号参数,它默认传递终止进程运行的信号给进程!

1
kill [options] <pid> [...]
  • <pid> […]:把信号发送给列出的所有进程。

  • options

    • -<signal>指定发送给进程的信号,指定信号的名称或号码都可以

    • -l:列出所有信号的名称和号码。

首先看 kill -lkill -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

本质上,killallkill命令一样,都是发送一条信号给指定的进程。

killall 用于杀死一个进程(kill processes by name),与 kill 不同的是它会杀死指定名字的所有进程。kill 命令杀死指定进程 PID,需要配合 ps 使用,而 killall 直接对进程对名字进行操作,更加方便。

killall 进程决不会杀死自己 (但是可以杀死其它 killall 进程)。

killall杀死进程的时候会把进程的子进程也杀掉

1
killall [选项]  name
  • -Z:只杀死拥有 scontext 的进程

  • -e:要求进程需要和名字完全相符,进程名称即ps -efcommandcmd字段,默认

  • -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类似,

1
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>

0%