ps/top/kill/后台任务/nohup + 面试高频信号 · 拆分自 Linux01 命令系统实战笔记
四、进程与后台任务:ps / top / kill / jobs / bg / fg / nohup
1. ps —— 查看进程快照(静态)
ps aux # 最常用:列出所有进程(BSD 风格)
ps -ef # 另一种风格(System V 风格)
ps aux | grep nginx # 过滤 nginx 相关进程
ps aux 关键字段:
| 字段 | 含义 |
|---|---|
| USER | 进程所属用户 |
| PID | 进程 ID(kill 靠它) |
| %CPU | CPU 占用率 |
| %MEM | 内存占用率 |
| VSZ | 虚拟内存大小 |
| RSS | 物理内存大小 |
| TTY | 关联终端 |
| STAT | 进程状态 |
| START | 启动时间 |
| TIME | 累计 CPU 时间 |
| COMMAND | 启动命令 |
STAT 状态码:
- R 运行(Running)
- S 可中断睡眠(Sleeping,最常见)
- D 不可中断睡眠(通常是 IO)
- T 被暂停(Stopped)
- Z 僵尸进程(Zombie)
- < 高优先级
- N 低优先级
2. top —— 实时进程监控(动态)
top
内部快捷键:
| 按键 | 作用 |
|---|---|
P |
按 CPU 占用排序 |
M |
按内存占用排序 |
k |
输入 PID 直接杀进程 |
1 |
展开显示每个 CPU 核心 |
q |
退出 |
h |
显示帮助 |
💡
htop是 top 的升级版(需要安装),更直观,支持鼠标操作。
3. kill —— 发送信号给进程
kill 1234 # 默认发送 SIGTERM(15),优雅终止
kill -15 1234 # 显式指定 SIGTERM
kill -9 1234 # SIGKILL,强制杀死
kill -1 1234 # SIGHUP,挂断(常用于重载配置)
killall nginx # 按程序名杀所有 nginx 进程
pkill -f "python app.py" # 按命令行匹配杀进程
🔑 面试高频:SIGTERM vs SIGKILL
- kill -15 (SIGTERM):默认信号,程序可以捕获、处理、保存数据后再退出,优雅关闭。
- kill -9 (SIGKILL):内核直接杀掉进程,程序无法捕获、无法清理,暴力终止。只在进程卡死无响应时才用。
4. jobs —— 查看当前终端的后台任务
jobs
jobs -l # 额外显示 PID
输出示例:
[1]+ Stopped sleep 600
[1]:任务编号(job number),不是 PID!fg/bg用这个编号。+:最近的任务;-:次近的任务。
⚠️ 核心限制:jobs 只能看当前终端的后台任务!新开一个终端,jobs 列表是空的。跨终端看进程用 ps/top。
5. fg —— 后台任务切到前台
fg 1 # 将编号 1 的后台任务切到前台
fg # 不带参数,默认操作最近的任务
前台程序占用终端,不能输入新命令。按 Ctrl+C 终止前台程序。
6. bg —— 暂停的任务在后台继续运行
bg 1 # 编号 1 的任务,后台继续运行
bg # 默认最近任务
典型操作流程:
python app.py # 前台运行
Ctrl+Z # 暂停当前前台程序,放到后台(暂停状态)
jobs # 查看任务编号
bg 1 # 在后台继续跑
fg 1 # 再切回前台
⚠️ 重要认知:bg 只是在当前 shell 会话内部后台运行,进程依然依附当前终端!关闭终端照样被杀。bg ≠ nohup!
7. nohup —— 忽略挂断信号,脱离终端运行
# & 表示放到后台;nohup 让进程忽略 SIGHUP
nohup python app.py &
输出默认重定向:nohup 会把 stdout/stderr 自动写入当前目录的 nohup.out。
🔑 面试必背:三种后台方式对比
| 写法 | 后台运行 | 关闭终端后 | 能用 jobs 看到 |
|---|---|---|---|
cmd & |
✅ | ❌ 被杀(SIGHUP) | ✅ |
| Ctrl+Z + bg | ✅ | ❌ 被杀(SIGHUP) | ✅ |
nohup cmd & |
✅ | ✅ 继续运行 | ❌(脱离作业管理) |
⚠️ 常见坑:
1. 只写 nohup cmd 不加 & → 前台卡住,没效果。
2. 只写 cmd & 不加 nohup → 关终端就死。
3. nohup 进程脱离了 shell 的作业管理,所以 jobs 看不到它,必须用 ps 查。
五、信号深入(面试高频)
四个容易混淆的信号
| 信号 | 编号 | 触发场景 | 默认动作 |
|---|---|---|---|
| SIGHUP | 1 | 关闭终端 / SSH 断开 | 终止进程 |
| SIGINT | 2 | 按 Ctrl+C | 终止进程 |
| SIGQUIT | 3 | 按 Ctrl+\ | 终止 + core dump |
| SIGTSTP | 20 | 按 Ctrl+Z | 暂停进程 |
| SIGTTIN | 21 | 后台任务读终端输入 | 暂停进程 |
| SIGTTOU | 22 | 后台任务写终端输出 | 暂停进程 |
| SIGTERM | 15 | kill 默认信号 | 优雅终止 |
| SIGKILL | 9 | kill -9 | 强制杀死(不可捕获) |
🔑 SIGTTOU 详解(很多教材漏掉的点):
交互式 bash 开启作业控制时,只有前台进程组拥有终端的读写权限:
- 后台任务读终端(stdin)→ 收到 SIGTTIN → 进程暂停(Stopped)
- 后台任务写终端(stdout/stderr)→ 收到 SIGTTOU → 进程暂停(Stopped)
但是否触发取决于终端的 tostop 设置:
stty -a | grep tostop # 查看当前设置
stty tostop # 开启:后台写终端 → SIGTTOU → 暂停
stty -tostop # 关闭:允许后台输出到终端(很多发行版默认)
部分环境/程序对 SIGTTOU 的处理是直接退出,表现为 jobs 显示
Terminated。标准默认信号动作是暂停,不是杀死。
评论