Linux 怎么 kill 进程?信号、kill/pkill/killall 一次讲清
答案:先 kill <PID>(发 SIGTERM=15,请求优雅退出),宽限期后仍不退出再 kill -9 <PID>(SIGKILL=9,内核强杀)。按名字用 pkill -f / killall,动手前先 pgrep 预览。
一、先找到 PID
ps aux | grep nginx | grep -v grep
pgrep -f 'java -jar app.jar' # -f 匹配完整命令行,比只匹配进程名更准
pidof nginx # 精确进程名返回 PID二、信号:TERM 与 KILL 的本质区别
kill 12345 # 默认 SIGTERM(15):请你退出,进程可捕获、保存数据、关连接
kill -15 12345 # 同上,显式写
kill -9 12345 # SIGKILL(9):内核强制回收,无法捕获/忽略,来不及清理
kill -2 12345 # SIGINT,等同 Ctrl+C
kill -1 12345 # SIGHUP,常用于让守护进程重载配置(如 nginx reload)| 信号 | 编号 | 作用 | 能否被捕获 |
|---|---|---|---|
| SIGTERM | 15 | 请求终止(kill 默认) | 能,可优雅清理 |
| SIGKILL | 9 | 强制杀死 | 不能,内核直接回收 |
| SIGINT | 2 | 终端中断(Ctrl+C) | 能 |
| SIGHUP | 1 | 挂起/常被复用为 reload | 能 |
一上来就
-9是坏习惯:进程没机会 flush 缓冲、提交事务、释放锁、通知对端,可能留下脏数据或端口/临时文件。正确姿势是 TERM → 等待 → 仍不退出才 KILL。服务优先systemctl stop,systemd 会先发 TERM、超过TimeoutStopSec再 KILL。
三、按名字/条件批量杀
pgrep -f worker.py # 先预览匹配到哪些 PID(强烈建议先跑)
pkill -f worker.py # 匹配完整命令行批量终止
pkill -TERM -f 'python.*batch' # 显式先发 TERM
killall nginx # 按精确进程名杀掉所有同名
pkill -u deploy # 杀某用户的全部进程(谨慎)
pkill -f匹配整条命令行,方便区分同名解释器跑的不同脚本;但也容易误伤,务必先用pgrep -f看清单。killall按精确名字,名字写错一般杀不到。
四、杀不掉怎么办
| 现象 | 原因 | 处理 |
|---|---|---|
kill -9 无效,STAT 为 D | 不可中断睡眠,卡在磁盘/内核 IO | 等 IO 返回;通常是 NFS/磁盘故障,根因在存储 |
进程是 Z/defunct | 已是僵尸,无法再杀 | 找父进程回收,见僵尸进程 |
Operation not permitted | 非属主/非 root | sudo kill |
| 杀完又出现 | 有守护/守护进程在拉起 | 停 systemd/supervisor/父进程,而非只杀子进程 |
五、退出码与 OOM
- 137 = 128 + 9:被 SIGKILL 终止。手工
kill -9或 OOM killer 都会得到它。容器里看到 137,结合dmesg/journalctl -k | grep oom判断是不是内存超了(见 OOM 排查)。 - 143 = 128 + 15:被 SIGTERM 正常请求停止(滚动发布、
systemctl stop常见)。
容器编排里这一区分很重要:Pod 退出 137 且节点有 oom 记录是内存 limit 太小,143 往往是正常滚动更新时的 SIGTERM。
FAQ
Q: kill 和 kill -9 区别? A: 默认 SIGTERM(15) 可被捕获优雅退出;SIGKILL(9) 内核强杀、无法捕获。先 15 后 9。
Q: 按名字批量杀? A: pkill -f 关键字(完整命令行)或 killall 名字,先 pgrep -f 预览。
Q: kill -9 都杀不掉? A: 多为 D 状态卡 IO(等存储恢复)、Z 僵尸(找父进程)或权限不足(sudo)。
Q: 137 是什么? A: 128+9,被 SIGKILL 终止,常见于强杀或 OOM;143=128+15 是 SIGTERM。
Q: 正确停止流程? A: 先 TERM 让应用清理,宽限期后再 KILL;服务用 systemctl stop 由 systemd 统一管理。
一句话总结:停进程先 kill(SIGTERM 优雅退出)后 kill -9(SIGKILL 强杀),按名批量用 pkill -f/killall 且先 pgrep 预览;D 状态等 IO、Z 状态找父进程、权限不够用 sudo;退出码 137=被 KILL(含 OOM)、143=TERM,服务优先 systemctl stop。