kill 是什么
kill 的本职是向进程发送信号,只是最常用的信号恰好是终止。kill PID 默认发 TERM(15),进程可以捕获它做清理后退出,这是优雅停止;kill -9 发 KILL,内核直接终结进程,不给清理机会,属于最后手段。给负数 PID 可以把信号发给整个进程组,是收尾一批相关进程的常用手法。
基本信息
| 适用平台 | Linux、Unix 通用(coreutils 与 BusyBox 都提供) |
|---|---|
| 命令语法 | kill [-信号 | -s 信号] PID... ;kill -- -PGID |
| 常用信号 | TERM(15) 优雅退出 / KILL(9) 强制终止 / HUP(1) 挂断或重载 / INT(2) 等价 Ctrl+C / USR1、USR2 应用自定义 |
| 权限要求 | 只能给自己名下的进程发信号;给他人进程发信号需要 root |
常用信号
| 信号 | 含义 | 典型用途 |
|---|---|---|
| 1 SIGHUP | 挂断,很多守护进程用它触发重载配置 | 不重启改配置 |
| 2 SIGINT | 中断,等同终端 Ctrl+C | 停止前台任务 |
| 9 SIGKILL | 强制终止,不可捕获也不可忽略 | 卡死进程的最后手段 |
| 15 SIGTERM | 请求优雅退出,进程可捕获后清理 | 默认信号,优先使用 |
| 18 / 19 | SIGCONT 继续 / SIGSTOP 暂停 | 恢复被暂停的进程 |
| 10 SIGUSR1 | 应用自定义语义 | 如让 nginx 重开日志文件 |
典型使用场景
- 停止卡住的进程:先发 TERM,等几秒观察,不退再上 KILL
- 重新加载配置:kill -HUP 进程号 让守护进程重读配置(程序需支持该信号)
- 停止一批同类进程:kill -- -PGID 对整组发送,避免逐个 PID
- 探测进程存活:kill -0 进程号 只做存在性与权限检查,不发送实际信号
- 查信号对照:kill -l 列出全部编号与名称
常用示例
常用示例
kill 1234 # 默认 TERM,优雅退出
kill -TERM 1234 # 同上,写信号名更清楚
kill -15 1234 # 用编号等价
kill -9 1234 # KILL:强杀,不给清理机会
kill -l # 列出所有信号的编号与名称
kill -l TERM # 查 TERM 对应的编号(15)
kill -0 1234 && echo alive # 只探测进程是否存在
kill -- -1234 # 发给进程组 1234(-- 结束选项解析)按名字批量发送
按名字批量发送
pkill -f 'python3 /opt/app/worker.py' # 按完整命令行匹配
pkill -TERM -u www nginx # 限定用户与进程名
killall -HUP rsyslogd # 按进程名发送 HUPsystemd 托管的服务不要直接 kill:进程被杀后 Restart= 策略可能立即把它拉起,或让 systemd 状态与实际不符。用 systemctl stop/restart,或 systemctl kill -s HUP 服务名 发信号。
尽量避开 kill -9:进程来不及刷盘、释放锁或删除临时文件,数据库类服务可能因此损坏,也可能留下僵尸进程与未清理的共享内存段。
选信号的原则
- 先试 TERM,给进程几秒钟清理并落盘的机会,多数程序在收到 TERM 后会自行退出
- 只有 TERM 无效或进程已无响应时才动 KILL,并且记下这次强杀的进程名与时间
- 改配置优先找程序文档里写明的重载信号,HUP 未必是每个程序的重载开关
- 收尾一批批处理进程时用进程组,避免只停掉父进程而留下孤儿
- 计划任务不要用 kill 停,改用 systemctl stop 或先注释掉对应的 crontab 条目
信号在具体程序中的语义
| 程序 | 信号 | 行为 |
|---|---|---|
| nginx | HUP | 重载配置并重新打开日志文件 |
| nginx | USR1 | 仅重新打开日志文件,logrotate 的 postrotate 常用 |
| nginx | USR2 | 平滑升级二进制,配合旧进程的 WINCH 与 QUIT 收尾 |
| sshd | HUP | 重载 sshd_config |
| rsyslogd | HUP | 重载日志规则配置 |
HUP 的原始含义是终端挂断,早期程序收到它默认退出;现代守护进程普遍把它重新定义为重载配置。所以 HUP 发给不支持该语义的程序(例如带终端的交互式进程),结果仍然是退出。
kill -0 适合写进脚本做存活检查:返回 0 表示进程存在且你有权限给它发信号,非 0 表示不存在或无权。它不发送任何有效信号,不会影响目标。
被 systemd 管理的服务优先用 systemctl stop 或 systemctl kill:单元文件里声明了结束方式与等待超时,systemd 会负责确认进程干净退出,也能避免自动重启策略立刻把进程拉回来,直接 kill 往往看不出效果。