ps
ps(process status)用于查看进程状态。它拍的是一张快照,执行完就结束,不会刷新 —— 要持续观察用 htop。
ps [选项]ps 有三套并存的选项风格:BSD 风格(不带
-,如ps aux)、UNIX 风格(带-,如ps -ef)、GNU 长选项(带--) 两种短风格的同名字母含义未必相同,ps aux和ps -aux不是一回事,别混着写
ps 不问内核要数据,它读的是 /proc 下的伪文件系统:每个进程对应一个 /proc/<PID>/ 目录,status、stat、cmdline 这些文件里放着它的全部状态。
所以 ps 的输出是执行那一瞬间遍历 /proc 的结果,不同进程的数据严格来说也不在同一时刻。
BSD 风格,不加连字符:
| 选项 | 说明 |
|---|---|
a |
显示所有用户的进程,不限于自己的 |
u |
面向用户的格式,带 CPU、内存占用 |
x |
包括没有控制终端的进程,也就是各种守护进程 |
f |
以树状显示父子关系 |
UNIX 风格,加连字符:
| 选项 | 说明 |
|---|---|
-e |
所有进程,等同 -A |
-f |
完整格式,带 PPID 和完整命令行 |
-l |
长格式,带优先级、状态、WCHAN |
-p <PID> |
只看指定的进程 |
-u <用户> |
只看指定用户的进程 |
-o <字段列表> |
自定义输出哪些列 |
--sort <字段> |
按字段排序,字段前加 - 为降序 |
--forest |
树状显示 |
1. 两条最常用的
ps aux # BSD 风格,看资源占用ps -ef # UNIX 风格,看进程关系ps aux 的列:
| 列 | 含义 |
|---|---|
| USER | 属主 |
| PID | 进程号 |
| %CPU | CPU 占用百分比,是自进程启动以来的平均值,不是瞬时值 |
| %MEM | 占物理内存的百分比 |
| VSZ | 虚拟内存大小(KB),包含映射了但没真正用的部分 |
| RSS | 常驻内存大小(KB),真正占着的物理内存 |
| TTY | 控制终端,? 表示没有 |
| STAT | 进程状态 |
| START | 启动时刻 |
| TIME | 累计占用的 CPU 时间 |
| COMMAND | 命令行 |
判断一个进程占多少内存看 RSS,不看 VSZ
STAT 列的字母:
| 字母 | 含义 |
|---|---|
R |
正在运行或在就绪队列里 |
S |
可中断睡眠,等 IO 或事件,绝大多数进程平时都是这个 |
D |
不可中断睡眠,通常卡在 IO 上,这种状态 kill -9 也杀不掉 |
T |
已停止,Ctrl-Z 之后就是它 |
Z |
僵尸,进程已经退出但父进程还没回收 |
< N |
高优先级、低优先级 |
s + l |
会话首进程、前台进程组、多线程 |
2. 自定义列并排序
ps -eo pid,ppid,user,%mem,rss,comm --sort=-%mem | head
-o只取关心的列,输出窄了才好读--sort=-%mem按内存降序,找吃内存的进程
3. 找特定的进程
ps -ef | grep nginxpgrep -a nginx
ps | grep会把 grep 自己也匹配进去,得再加一层grep -v greppgrep没这个问题,-a让它连命令行一起输出
4. 看进程树
ps -ef --forestps auxf排查「这个进程是谁拉起来的」时比平铺列表直观得多
5. 找僵尸进程
ps -eo pid,ppid,stat,comm | awk '$3 ~ /^Z/'僵尸进程只占一个进程表项,不占 CPU 和内存,也杀不掉 —— 它已经死了 要清掉得让父进程去回收,或者杀掉父进程,让 init 接管后代为回收
man psman 5 proc(/proc/<PID>/下各个文件的格式)