Linux ps 命令深度解析:从三种选项风格到进程查看实战
概述
在 Linux 里,ps(Process Status 的缩写)是看进程状态的核心命令——它能实时把系统里正在跑的进程信息抓出来,包括进程 ID(PID)、占了多少资源(CPU / 内存)、哪个用户在跑、啥时候启动的,这些关键数据全有。排查进程出问题(比如僵尸进程、某个进程狂吃资源)、或者开发调程序的时候,基本都离不开它。
跟大多数 Linux 命令“只有一套选项风格”不一样,ps 因为历史兼容性,同时支持 Unix、BSD、GNU 三种差别很大的选项风格,这也是新手最容易懵的地方(比如分不清 -ef 和 aux 到底差在哪)。这篇就从“选项风格分类”“核心命令实战”“进阶用法”三个角度,把 ps 的细节拆开讲,你按场景挑合适的命令用就行。
一、核心基础:ps 命令的三种选项风格
ps 这几种选项风格不一样,是因为它历史上要兼容 Unix、BSD 等不同系统的习惯,所以语法规则、选项意思都对不上。不过说到底,目的都是“把进程信息筛出来、显示出来”。先把每种风格的特点搞清楚,用 ps 才不会乱。
三种风格的核心区别
| 风格类型 | 语法特点 | 选项前缀 | 典型示例 | 适用场景 |
|---|---|---|---|---|
| Unix 风格 | 选项前加 -(短横线),选项可组合使用 | - | ps -ef、ps -efl | 查看系统全局进程、进程父子关系(运维常用) |
| BSD 风格 | 选项前不加任何前缀,选项可组合使用 | 无 | ps aux、ps auxw | 查看进程资源占用(CPU / 内存百分比)、用户维度进程 |
| GNU 风格 | 选项前加 —(双短横线),多为长选项 | — | ps —forest、ps —sort=-%cpu | 进阶功能(如进程树、按资源排序),可与前两种风格混用 |
关键提醒:
- 三种风格不可随意混合选项前缀(如不能写成 ps -aux 或 ps —ef),但 GNU 风格的长选项可与 Unix/BSD 风格组合(如 ps aux —forest);
- 日常使用中,Unix 风格的 -ef 和 BSD 风格的 aux 是最高频的两种命令,需重点掌握。
二、实战解析:高频 ps 命令与输出解读
下面挑三种风格里最常用的命令,一个一个讲“选项啥意思”“输出里每个字段怎么看”“适合啥场景”,你看完就能直接照着敲。
1. Unix 风格:ps -ef 与 ps -efl(全局进程与长格式)
Unix 风格的 ps -ef 是运维要查“系统里所有进程”时最先用到的命令,进程的完整信息(PID、父进程 ID、启动时间等)都能打出来;再加个 -l 选项,还会多给一份更细的“长格式”。
(1)ps -ef:查看系统所有进程
# 查看系统中所有运行的进程(Unix 风格)
ps -ef
选项含义:
- -e(equal to -A):显示所有进程(包括系统进程、用户进程,无任何过滤);
- -f(full format):输出 “完整格式”,包含更多关键字段(比默认格式多了 UID、PPID、STIME 等)。
输出字段解读(关键字段已标注):
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 08:00 ? 00:00:02 /sbin/init
root 2 0 0 08:00 ? 00:00:00 [kthreadd]
vagrant 1234 1000 0 09:30 pts/0 00:00:01 /usr/bin/python3
| 字段 | 含义 | 示例解读 |
|---|---|---|
| UID | 进程所属用户 ID | root 表示系统进程,vagrant 表示普通用户进程 |
| PID | 进程唯一 ID(核心字段) | 1 是系统初始化进程(init/systemd),所有进程的 “祖先” |
| PPID | 父进程 ID(Parent PID) | 1234 进程的父进程是 1000,可通过 PPID 找进程父子关系 |
| C | 进程占用 CPU 的百分比(单位:%) | 0 表示当前 CPU 占用低,数值越大占用越高 |
| STIME | 进程启动时间 | 08:00 表示进程在早上 8 点启动(若启动超过 24 小时,会显示日期) |
| TTY | 进程关联的终端 | ? 表示 “无终端关联”(多为系统后台进程),pts/0 表示关联到第 0 个虚拟终端 |
| TIME | 进程累计占用 CPU 的时间 | 00:00:02 表示进程从启动到现在共占用 2 秒 CPU 时间 |
| CMD | 进程的启动命令(含参数) | /usr/bin/python3 表示该进程是 Python3 程序 |
适用场景:
- 查找某个进程是否在运行(如 ps -ef | grep nginx 查看 Nginx 进程);
- 查看进程的父进程(通过 PPID 追溯进程来源,如排查 “谁启动了这个异常进程”)。
(2)ps -efl:长格式显示,补充进程状态
在 -ef 的基础上再加个 -l(long format)选项,会多显示“进程状态(STAT)”“优先级(PRI)”这些字段,想更细地分析进程时就用它:
ps -efl
新增关键字段:
| 字段 | 含义 | 示例 |
|---|---|---|
| STAT | 进程状态(核心字段) | R(运行中)、S(休眠中)、Z(僵尸进程)、T(暂停) |
| PRI | 进程优先级(数值越小优先级越高) | 20(默认优先级)、10(高优先级) |
| NI | 进程 nice 值(调整优先级的参数) | 0(默认)、-5(优先级更高)、10(优先级更低) |
示例输出(部分):
F S UID PID PPID C PRI NI ADDR SZ WCHAN STIME TTY TIME CMD
4 S root 1 0 0 80 0 - 56139 ep_pol 08:00 ? 00:00:02 /sbin/init
1 R vagrant 1234 1000 0 80 0 - 12345 - 09:30 pts/0 00:00:01 /usr/bin/python3
- 字段 STAT 中的 S 表示 “休眠中”(进程等待事件完成,如等待 IO),R 表示 “运行中”(正在占用 CPU 或等待 CPU 调度);
- 若出现 STAT 为 Z 的进程(僵尸进程),需通过 kill -9 父进程 PID 清理(僵尸进程已死亡,但父进程未回收其资源)。
2. BSD 风格:ps aux(资源占用与用户维度)
BSD 风格的 ps aux 是看“进程占了多少资源”的高频命令,输出更偏“用户视角”,会把 CPU 占用百分比(% CPU)和内存占用百分比(% MEM)都列出来,想快速找出哪个进程在狂吃资源就靠它。
命令格式:
# 查看所有进程(含无终端进程),按用户维度显示资源占用(BSD 风格)
ps aux
选项含义:
- a(all with tty):显示所有与终端关联的进程(包括其他用户的终端进程,不仅是当前用户);
- u(user-oriented format):输出 “用户导向格式”,重点展示资源占用字段(% CPU、% MEM、VSZ、RSS);
- x(exclude terminal-less):显示无终端关联的进程(如系统后台进程、守护进程,弥补 a 选项的遗漏)。
输出字段解读(核心关注资源字段):
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 100000 2048 ? Ss 08:00 0:02 /sbin/init
root 2 0.0 0.0 0 0 ? S 08:00 0:00 [kthreadd]
vagrant 1234 5.0 2.0 200000 40960 pts/0 R+ 09:30 0:10 /usr/bin/python3
| 字段 | 含义 | 示例解读 |
|---|---|---|
| USER | 进程所属用户名(比 UID 更直观) | root、vagrant |
| %CPU | 进程当前占用 CPU 的百分比 | 5.0 表示占用 5% CPU(数值超过 100 表示多线程进程,如 200 表示占用 2 个 CPU 核心) |
| %MEM | 进程占用物理内存的百分比 | 2.0 表示占用系统总内存的 2% |
| VSZ | 进程虚拟内存大小(单位:KB) | 200000 表示虚拟内存占用 200MB(包含代码、数据、共享库等) |
| RSS | 进程实际占用物理内存大小(单位:KB) | 40960 表示物理内存占用 40MB(比 VSZ 更能反映实际内存消耗) |
| START | 进程启动时间(格式更简洁) | 09:30 表示早上 9 点 30 分启动 |
| COMMAND | 进程启动命令(不含路径时显示简写) | python3 等同于 /usr/bin/python3 |
适用场景:
- 定位高 CPU / 内存占用进程(如 ps aux —sort=-%CPU 按 CPU 占用降序排列,快速找 “吃 CPU” 的进程);
- 按用户筛选进程(如 ps aux | grep vagrant 查看普通用户 vagrant 启动的所有进程)。
实用技巧:按资源排序
用 GNU 风格的 —sort 选项,能让 ps aux 直接按 CPU 或内存占用排好序,省得自己手动 grep 去筛:
# 按 CPU 占用降序排列(%CPU 从高到低)
ps aux --sort=-%CPU
# 按内存占用降序排列(%MEM 从高到低)
ps aux --sort=-%MEM
3. GNU 风格:ps —forest(进程树与层级关系)
GNU 风格的 —forest 选项简直是“把进程父子关系画出来”的神器,它会用竖线和横线画出一棵进程树,谁是父进程、谁是子进程一目了然,特别适合排查“进程之间怎么衍生出来的”(比如 Nginx 的主进程和工作进程)。
命令格式(可与 Unix/BSD 风格组合):
# 结合 BSD 风格,用进程树显示所有进程
ps aux --forest
# 结合 Unix 风格,显示 Nginx 进程的层级关系
ps -ef --forest | grep nginx
示例输出(ps aux —forest 部分结果):
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 500 0.0 0.2 120000 4096 ? Ss 08:05 0:00 nginx: master process /usr/sbin/nginx
www-data 501 0.0 0.1 120500 2048 ? S 08:05 0:00 \_ nginx: worker process
www-data 502 0.0 0.1 120500 2048 ? S 08:05 0:00 \_ nginx: worker process
vagrant 1000 0.0 0.3 150000 6144 pts/0 Ss 09:00 0:00 bash
vagrant 1234 5.0 2.0 200000 40960 pts/0 R+ 09:30 0:10 \_ python3
解读:
- nginx: master process(PID 500)是 “主进程”,下面两个 nginx: worker process(PID 501、502)是它的 “子进程”(用 _ 标识);
- bash(PID 1000)是用户登录后的终端进程,python3(PID 1234)是在 bash 中启动的子进程,说明 python3 是通过终端命令启动的。
适用场景:
- 排查 “进程簇” 关系(如查看 Tomcat 的主进程与子线程、Docker 容器进程的父进程);
- 确认进程是否 “正确衍生”(如 Nginx 主进程是否成功启动工作进程)。
三、常用组合:ps 与 grep/awk 搭配筛选进程
平时用 ps,经常跟 grep(按关键词过滤)、awk(提取某一列)搭着用,实现“精准筛进程”或者“抠出关键信息”,下面几个组合最高频。
1. 查找指定进程(如 Nginx、Python)
# 查找 Nginx 相关进程(排除 grep 自身进程)
ps -ef | grep nginx | grep -v grep
# 查找 Python3 进程(BSD 风格,显示资源占用)
ps aux | grep python3 | grep -v grep
- 加 grep -v grep 是为了排除 “grep nginx” 这个临时进程(避免结果中出现无关的 grep —color=auto nginx 条目)。
2. 提取指定进程的 PID(用于 kill 或监控)
# 提取 Nginx 主进程的 PID(用 awk 取第 2 列,即 PID 列)
ps -ef | grep "nginx: master process" | grep -v grep | awk '{print $2}'
# 将 PID 赋值给变量,用于后续 kill 操作
NGINX_PID=$(ps -ef | grep "nginx: master process" | grep -v grep | awk '{print $2}')
kill -HUP $NGINX_PID # 平滑重启 Nginx
3. 查看指定用户的所有进程
# 查看用户 vagrant 启动的所有进程(Unix 风格)
ps -ef | grep vagrant | grep -v grep
# 查看用户 root 的进程(BSD 风格,显示资源占用)
ps aux | grep ^root | grep -v grep
- grep ^root 中的 ^ 表示 “以 root 开头”,确保只匹配 USER 字段为 root 的进程,避免匹配到命令中包含 root 的进程。
四、总结:ps 命令的核心使用场景与选型
ps 灵活就灵活在“不同选项风格对应不同需求”,不用死背所有命令,按实际场景挑对应的高频组合就行。下面列的是日常运维 / 开发最常碰到的场景和最顺手的命令搭配,直接套就能解决问题:
| 核心需求 | 推荐命令 | 选型理由 |
|---|---|---|
| 1. 查看系统所有进程,追溯父子关系 | ps -ef | Unix 风格经典命令,完整展示 PID(进程 ID)、PPID(父进程 ID),方便排查 “某个进程由谁启动”,是运维定位进程来源的首选 |
| 2. 快速定位高 CPU / 内存占用进程 | ps aux —sort=-%CPU(按 CPU 排序)|ps aux —sort=-%MEM(按内存排序) | BSD 风格的 aux 自带 % CPU、% MEM 字段,直观显示资源占用;结合 GNU 风格的 —sort 选项,无需手动筛选,直接按资源消耗降序排列,秒找 “资源大户” |
| 3. 可视化查看进程层级(如服务主 / 子进程) | ps aux —forest(全局进程树)ps -ef —forest | grep 服务名(指定服务树) | —forest 选项用 “竖线 + 下划线” 绘制进程树,清晰区分主进程与子进程(如 Nginx 主进程与工作进程、Docker 容器进程与父进程),适合确认服务是否正常衍生子进程 |
| 4. 查找指定进程并获取 PID(用于 kill / 重启) | ps -ef | grep “关键词” | grep -v grep | awk ‘{print $2}’ | 组合 grep 过滤关键词(如进程名、启动命令),grep -v grep 排除临时筛选进程,awk 提取 PID 列,可直接赋值给变量用于后续操作(如 kill $PID 关闭进程) |
| 5. 查看指定用户的所有进程(如普通用户 /root) | ps aux | grep ^用户名(如 ps aux | grep ^vagrant) | BSD 风格的 aux 以 USER 字段开头,grep ^用户名 精准匹配该用户的所有进程,避免命令中包含用户名的无关结果,适合排查 “某用户启动了哪些进程” |
一句话,ps 的核心就是“按你要的信息去筛”:
- 想看进程之间关系用 ps -ef,想看资源占用用 ps aux,想看层级结构就加个 —forest;
- 碰到复杂需求(比如筛选、抠出 PID),只要配上 grep/awk,进程信息就能从“一团乱麻的输出”变成“精准的结果”。