
ps命令基础:最常用的两个命令,90%的人都分不清区别
说到ps命令,你最先想到的是不是ps aux或者ps -ef?我敢说至少一半的人都是随便敲一个,能看到进程列表就行。但这两个命令的区别,直接决定了你能不能拿到关键信息。去年帮一个刚接手服务器的朋友排查问题,他用ps -ef查了半天,说”进程都在啊,没看到哪个占内存高”,我让他换成ps aux | sort -k4nr | head -5,结果第五行就躺着一个占用85%内存的Java进程——这就是没搞懂基础命令差异的坑。
ps aux和ps -ef,到底该用哪个?
这两个命令的核心区别,其实是 Unix 两种风格的延续:ps aux 是 BSD 风格,ps -ef 是 System V 风格(也就是我们常说的 SysV 风格)。你不用记这么专业的名词,只要记住它们输出的列不一样,适用场景也不同:
ps aux sort=-%mem | head
ps -ef | grep 进程PID
就能看到它的父进程,顺着PPID一路往上查,常常能揪出恶意程序的根源。我平时的习惯是:排查资源占用用 ps aux,追踪进程关系用 ps -ef。记住这个小技巧,你就能比别人快一步定位问题。
必须掌握的5个核心参数,够用90%的场景
除了 aux 和 -ef,ps 还有很多参数,但你真正常用的其实就几个。我整理了一张表格,把最实用的参数和用法列出来,你可以存手机里,下次记不住就翻一翻:
参数 | 作用 | 实用示例 | 场景 |
---|---|---|---|
-e | 显示所有进程(等价于 -A) | ps -e | grep sshd | 检查特定服务是否运行 |
-f | 显示完整格式(包含UID、PPID等) | ps -ef | grep nginx | 查看进程的启动用户和父进程 |
-o | 自定义输出列 | ps -eo pid,comm,%cpu sort=-%cpu | 按CPU使用率排序进程 |
-u | 按用户筛选进程 | ps -u www-data | 查看网站服务(www-data)的所有进程 |
sort | 按指定列排序(+升序,-降序) | ps aux sort=-%mem | 找出内存占用最高的进程 |
这里要特别说一下 -o
参数,它是自定义输出的神器。比如你只想看进程的PID、状态和命令名,直接用 ps -eo pid,stat,comm
,输出清爽不杂乱;如果要排查哪个用户占用资源多,就用 ps -eo user,pid,%cpu,%mem sort=-%cpu
,用户和资源占用一目了然。我之前处理过一个服务器负载高的问题,就是用 -o
参数只显示关键列,30秒就定位到是某个测试用户跑的Python脚本占用了90%的CPU。
进阶技巧:从状态码到实战,学会这几招才算真会用ps
掌握了基础参数,你已经能应付大部分日常查看了。但遇到异常进程时,真正能帮你解决问题的,是看懂进程状态码,以及知道怎么针对性排查。比如看到状态是”D”的进程,你敢直接kill吗?我见过有人因为乱杀”D”状态进程,导致数据库文件损坏,最后花了一下午恢复数据——这就是没搞懂状态码含义的代价。
进程状态码(R/S/D/T/Z)全解析,这5个字母必须牢记
ps命令输出的”STAT”列里,这些字母不是随机出现的,每个都代表进程当前的状态,看懂它们,你就能判断进程是正常运行还是出了问题:
ps aux | grep R
看到一堆R状态的进程,不用慌,这很正常,系统本来就是多进程并发的。kill -CONT PID
让它继续运行。比如你跑一个脚本时按了Ctrl+Z,用ps一看状态就是”T”,这时用fg命令就能把它调回前台。kill -HUP 父进程PID
让父进程回收它就行。我上周刚帮朋友处理过,他服务器上有20多个僵尸进程,查PPID发现是一个写得不好的Node.js服务,重启服务后僵尸进程全没了。3个实战场景,学会了就是系统管理高手
光看懂状态码还不够,遇到具体问题时怎么用ps命令排查?分享3个我工作中最常用的场景,每个都给你现成的命令,抄过去就能用:
场景1:服务器卡顿,快速找出高CPU进程
CPU突然飙升时,别慌着重启服务,先用ps定位问题。我习惯用这个命令:
ps -eo %cpu,pid,user,comm sort=-%cpu | head -10
它会按CPU使用率从高到低排序,显示前10个进程。%cpu列是CPU使用率,pid是进程ID,user是运行用户,comm是命令名。比如有一次线上服务器CPU到了95%,用这个命令发现”php-fpm”进程占了80%,再查Nginx日志,原来是有爬虫在短时间发了10万次请求,导致php-fpm进程疯狂创建。这时不用重启服务器,先临时限制爬虫IP,再调大php-fpm的最大进程数,5分钟就恢复正常了。
场景2:内存告警,揪出内存占用大户
内存占用高比CPU更隐蔽,因为有些进程会悄悄吃内存直到系统Swap耗尽。这时用这个命令:
ps aux sort=-%mem | awk '{print $4,$2,$11}' | head -15
aux输出里的%mem列就是内存使用率,sort=-%mem按降序排列,awk命令提取第4列(%mem)、第2列(PID)和第11列(命令名),避免输出太乱。上周帮客户排查一台内存不足的服务器,用这个命令发现一个”java”进程占了60%内存,查JVM参数才发现Xmx设置成了物理内存的90%,导致没有剩余内存给其他服务,调小Xmx后问题解决。
场景3:清理僵尸进程,避免PID耗尽
僵尸进程虽然不占资源,但积累多了会导致新进程无法创建(Linux系统PID数量有限,通常是32768个)。排查僵尸进程的命令很简单:
ps -ef | grep defunct | grep -v grep
输出里带””的就是僵尸进程,比如”1234 ? 00:00:00 sh “。这时看它的PPID列(父进程ID),比如PPID是567,就用 kill -HUP 567
让父进程回收。如果父进程本身也出了问题(比如状态是”Z”或不响应),那就只能重启父进程了。根据Red Hat的文档(https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/system_administrators_guide/sec-managing_processes,nofollow),僵尸进程本身不会导致系统崩溃,但及时清理能避免潜在风险。
这些技巧都是我在无数次排查问题中 出来的,你不用死记硬背,遇到对应的场景直接翻出来用就行。比如下次服务器变慢,先别急着喊运维,自己用 ps aux sort=-%mem
看看内存,或者 ps -eo %cpu,pid,comm sort=-%cpu
查CPU,大概率能找到问题所在。如果试了这些方法还是解决不了,也欢迎在评论区留言,把你的ps命令输出和问题场景告诉我,我们一起看看是哪里出了问题。
你在看ps命令输出的时候,是不是经常盯着STAT那一列发懵?那些R、S、D、Z字母到底是啥意思?别着急,我一个个给你掰扯清楚,都是平时管理服务器时踩过的坑 出来的经验,保证你听完就明白。
先说最常见的R状态,你平时敲个命令跑个程序,只要它在运行,状态基本就是R——不过这里的“运行”得打个引号,它其实是“可运行”的意思。要么是正在CPU上真刀真枪地干活,要么是排着队等CPU有空了轮到它。比如你用ps aux | grep R
搜一下,可能会看到好几个R状态的进程,这很正常,系统本来就是多任务并发的,CPU在进程间切换快得很,咱们肉眼根本看不出来。
然后是S状态,睡眠状态,这才是进程的“常态”。你想啊,大部分程序大部分时间都在等事儿干——等你输个命令、等网络数据过来、等硬盘读完文件,这时候就会进入S状态。比如你开个终端没操作,里面的bash进程状态就是S,前面可能还带个“+”号,表示它是前台进程,你一关终端它就跟着退出了。不过有种特殊情况要注意,S状态前面要是带个L,说明这进程锁住了内存,一般是数据库或者高优先级程序才会这样,别随便动它。
重点来了,那个D状态,你可千万要记住,这玩意儿堪称“服务器管理刺客”。D是“不可中断睡眠”的意思,说白了就是进程正在跟硬件打交道——比如读硬盘、连NAS存储、或者等外接设备响应。这时候内核会死死按住它,不让任何人打断,你就算祭出kill -9这个“终极杀器”都没用。去年我帮一个客户处理服务器,他们存储阵列突然断连,ps一看好家伙,五六个D状态的进程卡在那儿,有个新手运维非要强行重启,结果导致文件系统损坏,恢复数据花了一下午。正确做法是啥?先别急着动手,等!等存储恢复连接,或者硬盘读完数据,进程自己就会从D状态出来;要是等了半小时还卡着,那十有八九是硬件出问题了,赶紧检查硬盘线、存储交换机这些链路。
最后说Z状态,僵尸进程,听着吓人其实没那么可怕。这就像子进程退出了,但它爹(父进程)太忙忘了给它“收尸”,导致资源没回收干净,变成了“僵尸”。你用ps一看,进程名后面会带个标记。这种进程不占CPU也不占内存,就是占个PID号,要是积累多了(比如几百个),新进程可能就起不来了。处理方法也简单:先用
ps -ef | grep defunct
找到它的PPID(父进程ID),然后给父进程发个HUP信号(kill -HUP 父进程PID),让它想起来还有个“孩子”没处理。我上周刚处理过一个Node.js服务,父进程没写好回收逻辑,僵了二十多个子进程,一发HUP信号,秒秒钟就清净了。
ps aux和ps -ef有什么核心区别?什么时候该用哪个?
核心区别在于输出列和适用场景:ps aux是BSD风格,输出包含%cpu(CPU使用率)、%mem(内存使用率)、VSZ(虚拟内存)、RSS(物理内存),适合排查资源占用问题,比如按内存排序找占用大户;ps -ef是SysV风格,输出包含PPID(父进程ID)、C(CPU使用率整数),适合追踪进程树关系,比如通过PPID查异常进程的父进程。简单说:看资源用aux,追关系用-ef。
进程状态码里的R、S、D、Z分别代表什么?遇到D状态进程该怎么办?
R是运行/就绪状态(正在CPU运行或排队等待),S是睡眠状态(等待事件如键盘输入),D是不可中断睡眠(等待I/O如读硬盘,内核不允许中断),Z是僵尸状态(子进程退出后父进程未回收资源)。遇到D状态进程千万别强行kill(kill -9也无效),需等待I/O操作完成(如存储恢复连接),若长时间卡着,检查硬件或存储链路是否故障。
如何用ps命令快速找出占用CPU或内存最高的进程?
查内存占用最高:用ps aux sort=-%mem | head,按%mem降序排列并显示前10行;查CPU占用最高:用ps -eo %cpu,pid,comm sort=-%cpu | head,自定义输出CPU使用率、PID、命令名并按CPU降序。比如想找前5个内存大户,直接加head -5:ps aux sort=-%mem | head -5。
发现僵尸进程(Z状态)该怎么处理?能直接kill吗?
僵尸进程(带标记)是父进程未回收子进程资源导致的,直接kill僵尸进程本身无效(它已终止)。正确做法:先用ps -ef | grep defunct找到僵尸进程的PPID(父进程ID),然后用kill -HUP 父进程PID让父进程回收资源;若父进程无响应,重启父进程即可。比如PPID是1234,执行kill -HUP 1234,僵尸进程通常会消失。
为什么有时候用ps命令看不到某些进程?是命令用错了吗?
可能有两个原因:一是权限问题(普通用户看不到root用户的进程,需用sudo ps);二是进程短暂存在(比如瞬时启动的脚本),ps命令是“快照”,可能刚好错过。 用ps -e(显示所有进程)或结合grep缩小范围(如ps -ef | grep 进程名),若仍看不到,用top命令实时监控,或检查进程是否已退出。