当前位置:首页>Linux>别再只会 kill -9 了!Linux 终止进程三剑客(kill/killall/pkill)终极避坑指南

别再只会 kill -9 了!Linux 终止进程三剑客(kill/killall/pkill)终极避坑指南

  • 2026-10-11 05:43:42
别再只会 kill -9 了!Linux 终止进程三剑客(kill/killall/pkill)终极避坑指南

服务器凌晨三点卡住了,SSH 登上去,进程占着 CPU 不撒手。你打开 ps aux,盯着屏幕上一列列数字,脑子里只有一个问题:

怎么把它干掉?

大多数人面对卡死的服务,第一反应就是 kill -9。,但你可能不知道,kill -9` 其实是最粗暴的最后手段,Linux 系统给你准备了一套更精细的工具。

这篇文章从历史讲起,带你搞清楚 kill、killall、pkill 三条命令的来龙去脉,以及在什么场景下用哪一个。


先聊聊"信号"——进程之间的暗语

在讲命令之前,得先说一件事:kill 这个名字其实有点误导人,它的本质不是"杀死",而是向进程发送一个信号(signal)。

信号是 Unix/Linux 进程间通信的最古老机制之一,就像两个士兵之间发暗号——收到信号的进程自己决定怎么处理。

常用的信号就那么几个:

信号编号
信号名称
含义
1
SIGHUP
挂起,常用于让进程重新加载配置
2
SIGINT
中断,等价于键盘 Ctrl+C
9
SIGKILL
强制终止,进程无法拦截
15
SIGTERM
请求终止(默认),进程可以做清理再退出

SIGTERM 是有礼貌的"我走了,你也收拾收拾吧",SIGKILL 是不讲道理的"你现在就得死"——前者进程可以拒绝或延后,后者进程没有任何反抗余地。

所以,kill -9 并不是 kill 的"正确用法",而是当正常方式失效时的核武器。


kill:Unix 1972 年就有的老祖宗

kill 命令的历史出乎意料地长。根据 Unix 历史记录,信号机制最早出现在 Unix Version 2(1972年),到 Unix Version 7(1979年)才完善了完整的信号名称体系。也就是说,这条命令已经活了 50 多年了。

它的用法很简单,只有一个核心逻辑:你得先知道进程的 PID(进程号)。

# 查进程 PIDps aux | grep nginx# 用 PID 发 SIGTERM(默认信号,优雅终止)kill 1234# 发 SIGKILL(强制终止,进程无法拒绝)kill -9 1234# 让 nginx 重新加载配置(不重启进程)kill -HUP 1234# 一次终止多个进程kill 1234 5678 9012

典型场景:定向精准打击

你在服务器上部署了多个 Python 脚本,只想停掉 PID 为 4567 的那一个,不影响其他的。这时候 kill 4567 是最稳妥的选择——手术刀,不是榔头。

kill 的短板

用 kill 的前提是你得先找到 PID,两步走,还容易看花眼。当进程有几十个的时候,这就很折磨人了。这个痛点,催生了后来的两个工具。


killall:按名字终止,来自 psmisc 工具集

killall 让你可以直接用进程名而不是 PID 来终止进程,省去了查 PID 这一步。

但这里有个必须提的陷阱:killall 有两种完全不同的实现。

  • • System V(Solaris)版本:killall 会终止所有你有权限终止的进程,如果是 root 执行,效果等于让系统崩溃——它真的会把整个系统进程全部清光,所以在 Solaris 上它只用于系统关机流程。
  • • Linux psmisc 版本:只终止你指定名字的进程,安全可控。

现在 Linux 上用的是 psmisc 版本,行为是安全的。

# 终止所有名为 nginx 的进程killall nginx# 强制终止killall -9 firefox# 忽略大小写匹配进程名killall -I Java# 终止某个用户运行的所有 nginx 进程killall -u www-data nginx# 终止运行超过 10 分钟的 python3 进程killall -o 10m python3# 让 nginx 重载配置(不停服)killall -HUP nginx

典型场景:一键重启所有 Nginx Worker

你修改了 nginx.conf,需要让所有 nginx 进程重新加载配置,但又不想重启服务:

killall -HUP nginx

一条命令,所有 nginx worker 都收到 SIGHUP,优雅地重新读取配置,用户几乎无感知。

killall 的特点:精确匹配

killall 要求进程名完全匹配。比如进程名叫 python3,你敲 killall python 会提示"no process found"。这个特点让它在批量终止同名进程时非常安全,不会误伤。


pkill:1998 年 Solaris 带来的模式匹配革命

pkill 出现于 1998 年的 Solaris 7,最初和 pgrep 配套推出,后来被移植到 Linux(由 procps-ng 包提供)。

它和 killall 的最大区别在于:pkill 支持模糊匹配和正则表达式,不需要写完整进程名。

# 按进程名(支持部分匹配)pkill nginx# 用正则表达式匹配pkill -r "py.*3"# 终止某个用户的所有进程(踢掉一个用户的全部会话)pkill -u xiong# 只终止进程名完整匹配的进程(类似 killall 的行为)pkill -x nginx# 终止占用特定终端的进程pkill -t pts/1# 找到父进程 PID 为 1234 的所有子进程并终止pkill -P 1234# 先用 pgrep 查看会匹配哪些进程,确认后再 pkillpgrep -l "java"pkill java

典型场景一:清理一个用户的所有进程

某个测试账号跑了一堆乱七八糟的进程,你想一键清空:

pkill -u testuser

所有属于 testuser 的进程全部收到 SIGTERM,干净利落。

典型场景二:终止一组相关进程

你的机器上跑了多个版本的 Java 程序,名字分别是 java、java11、java17,你想把它们都停掉:

pkill -r "java"

用正则一网打尽,而 killall java 只会终止名字精确为 java 的那些。


三剑客横向对比

维度
kill
killall
pkill
查找方式
PID
精确进程名
进程名 / 正则 / 用户 / 终端
是否需要查 PID
是
否
否
支持模糊匹配
否
否
是
精准度
最高
高(不误伤同名)
中(需小心正则)
批量操作
需手动列 PID
自动匹配所有同名进程
支持多维度批量
来源
Unix V2 (1972)
psmisc / FreeBSD
Solaris 7 (1998)

选哪个?一个简单原则:

  • • 知道 PID,只终止一个进程 → kill
  • • 按进程名批量终止,名字确定 → killall
  • • 名字不确定、需要模糊匹配、按用户/终端批量 → pkill

一个高频误区:kill -9 不是首选

很多人遇到进程不响应,第一反应就是 kill -9。

但 SIGKILL 的问题在于:进程没有机会做清理。数据库来不及刷盘、临时文件来不及删除、网络连接来不及优雅断开——轻则留下一堆脏数据,重则下次启动报错甚至数据损坏。

正确的姿势是先 SIGTERM,等几秒,再 SIGKILL:

# 先礼貌地请它走kill -15 <PID>sleep 5# 如果还在,再强制终止kill -9 <PID>

或者用 pkill/killall 的组合:

pkill nginxsleep 3pkill -9 nginx

这个两步流程,是线上服务优雅下线的标准做法。


kill、killall、pkill 三条命令,背后是 Unix 五十年来对"如何控制进程"这个问题的持续思考。从需要手动查 PID,到按名字匹配,再到支持正则和多维度筛选——工具越来越趁手,但信号机制这套底层语言从未改变。

下次再遇到进程跑飞,记得先 SIGTERM,再考虑 SIGKILL。


最新文章

随机文章