草稿待审 — 全部命令已在 WSL2 Ubuntu 24.04 实测通过
TL;DR:nohup 会让进程忽略 SIGHUP,但正常信号仍然有效。推荐顺序:先 kill -TERM <PID> 优雅退出,不行再加 kill -KILL <PID> 强杀。pkill -f <关键词> 和 killall <程序名> 适合批量或忘了记录 PID 的场景。
为什么 nohup 进程不响应关闭
nohup 在 POSIX 规范中明确:启动时会将 SIGHUP 设为忽略,所以终端关闭不会让进程退出[1]。但这个行为只影响 SIGHUP(信号 1),进程仍然可以接收 SIGTERM(15)、SIGKILL(9)等其他信号。关不掉的原因通常是:没给 PID、权限不够、或进程进入 uninterruptible sleep 状态。
方法一:用 kill 指定 PID 优雅退出
这是最可控的方式。
# 1. 找到 nohup 进程的 PID
ps aux | grep -E "nohup|你的程序名" | grep -v grep
# 输出示例:root 12345 0.0 0.1 123456 7890 pts/0 S+ 08:00 0:00 nohup python3 server.py
# 2. 发送 TERM 信号(默认,优雅退出)
kill 12345
# 3. 确认是否退出
ps aux | grep "12345" | grep -v grep
# 没输出 = 已退出
kill 默认发送 SIGTERM[2],进程可以拦截并做清理(关文件、写日志),优于直接强制杀。kill -TERM <PID> 和 kill <PID> 等价[3]。
# 进程不响应 SIGTERM 时,升级为 SIGKILL(不可拦截,立即终止)
kill -KILL 12345
方法二:pkill 按名称查找并杀
忘记记录 PID 时,用 pkill 匹配进程名或完整命令行[4]:
# 匹配命令行中包含 "server.py" 的进程
pkill -f "server.py"
# 指定发送 SIGTERM(默认已是 TERM,显式写更清晰)
pkill -f -TERM "server.py"
# 直接发 SIGKILL(慎用)
pkill -9 -f "server.py"
-f 匹配完整命令行;不加 -f 只匹配进程名(第 0 列)。
# 验证
pgrep -f "server.py"
# 无输出 = 已杀掉
方法三:killall 按程序名批量杀
killall 直接按可执行文件名发信号[5],适合知道进程名的情况:
# 杀掉所有 python3 进程(慎用!会杀所有同名进程)
killall python3
# 发送 SIGKILL
killall -9 python3
和 pkill 的区别:killall 不需要 -f,匹配的是可执行文件名,更简洁但也更容易误杀同名进程。
排错速查表
| 现象 | 原因 | 处理 | |
|---|---|---|---|
| kill: not enough arguments | 没填 PID | `ps aux \ | grep <关键词>` 找到 PID |
| kill: (12345) – Operation not permitted | 进程属于别的用户 | 用 sudo kill 12345 |
|
| kill: (12345) – No such process | PID 已不存在 | 不需要再杀 | |
| 进程还在,SIGTERM 无效 | 进程卡在 D 状态或屏蔽了信号 | kill -KILL <PID> |
|
| pkill/killall 什么都没杀 | 匹配模式不对 | 加 -f 或换进程名再试 |
关于 nohup.out 文件
进程结束后,nohup.out 或你重定向的输出文件不会被自动删除。实测:kill -9 终止进程后,输出文件仍留在磁盘上(内容可能为空)。确认进程退出后手动清理:
rm -f nohup.out /path/to/your_output.log
局限性
- 本指南实测环境为 WSL2 Ubuntu 24.04;SIGKILL 对卡在 uninterruptible sleep(D 状态)的 I/O 进程可能无效,真机上需检查
dmesg。 killall匹配的是可执行文件名,同名进程会一起被杀,生产环境建议先用pgrep确认。- 以下命令属于核心工具集(coreutils / psmisc / procps),Ubuntu/Debian 默认已安装,无需额外安装。
附录:本次 WSL 实测记录
- 测试机:WSL2 Ubuntu 24.04(systemd 启用)
- 测试时间:2026-11-04 08:00 CST
- WSL 实测通过:
kill -TERM <PID>:进程正常退出 ✓kill -KILL <PID>:进程立即终止 ✓pkill -f <关键词>:按命令行匹配成功 ✓killall -9 <名>:按可执行文件名强杀成功 ✓- nohup.out 文件在 kill 后仍存在(空文件)✓
- 清理状态:所有测试进程已清除,无残留
附录:参考资料
- [1] nohup(1p) POSIX 手册,https://man7.org/linux/man-pages/man1/nohup.1p.html,访问日期:2026-11-04
- [2] kill(1) Linux 用户命令手册,https://man7.org/linux/man-pages/man1/kill.1.html,访问日期:2026-11-04
- [3] GNU Coreutils kill 调用说明,https://www.gnu.org/software/coreutils/manual/html_node/kill-invocation.html,访问日期:2026-11-04
- [4] Debian bookworm pgrep(1),https://manpages.debian.org/bookworm/procps/pgrep.1.en.html,访问日期:2026-11-04
- [5] Debian bookworm killall(1),https://manpages.debian.org/bookworm/psmisc/killall.1.en.html,访问日期:2026-11-04
FAQ
Q1:nohup 进程后台跑了,关了终端它还在吗? 在的。nohup 自动忽略 SIGHUP,关闭终端不会影响它。
Q2:kill 和 kill -9 哪个更安全? kill(即 SIGTERM)让程序有机会自己清理,比如关数据库连接、写日志。SIGKILL(9)进程来不及反应,适合 TERM 无效时再用。
Q3:pkill 和 killall 有什么区别? pkill -f "关键词" 匹配完整命令行;killall 程序名 匹配可执行文件名,更简洁但误杀风险更高。
Q4:为什么进程被杀了 nohup.out 还在? nohup 不会自动清理输出文件,确认进程退出后手动 rm。
Q5:root 用户能杀其他用户的进程吗? 可以,sudo kill <PID> 即可;反过来普通用户杀 root 进程会报 Operation not permitted。
参考资料
- [1] man7-nohup(man7-nohup)
- [2] man7-kill(man7-kill)
- [3] gnu-kill(gnu-kill)
- [4] deb-pgrep(deb-pgrep)
- [5] deb-killall(deb-killall)
文中主要命令已在 WSL Ubuntu(24.04)实测,个别条目(未装工具/安装类命令)仅核对官方文档,未实际执行。