在 Linux 上查进程,多数时候要回答的只有四个问题:进程还在不在、PID 是多少、谁启动的、占了多少 CPU 和内存。能直接回答这些的是 ps、pgrep、top,以及 /proc/<PID>/ 下的几个文件;先跑哪条,取决于你要的是一次性快照,还是持续观察。
判断顺序建议这样走:先用pgrep -a或ps -eo拿到 PID,再用/proc/<PID>/status和exe确认这个 PID 确实是你要找的进程,最后才用top -p或ps -L看资源和线程。ps 里的 %CPU 通常是进程整个生命周期的平均值,不适合用来判断“现在是不是它占满了 CPU”,要看瞬时值得用 top 或 pidstat。进程处于 D 或 Z 状态时 kill 不生效属于常见现象,先看 State 字段再决定下一步。
查看进程的命令:先把能核对的事实摆清楚
要被查看的对象是进程,能被核对的是它的属性:PID、父进程 PPID、所属用户 UID、状态 State、启动时的完整命令行、可执行文件路径、工作目录、打开的句柄。这些属性在两类地方能看到——命令输出,和 /proc 文件系统。
- 一次性快照:
ps -ef给 PID、PPID、UID、CMD;ps aux给 USER、PID、%CPU、%MEM、STAT、START、COMMAND。两者字段名不同,看到的进程集合一般一致。 - 按名字找:
pgrep -a 进程名输出 PID 加完整命令行;pgrep -f匹配整条命令行而不是进程名。 - 持续观察:
top默认按 CPU 排序,界面里按P按 CPU、M按内存重排。 - 直接读内核视角:
/proc/<PID>/cmdline(参数以 \0 分隔)、/proc/<PID>/status(State、PPid、Uid、Threads)、/proc/<PID>/exe(软链到真实二进制)。
前提条件需要先确认,否则命令会给出误导性的结果。一是 ps 的版本:用 ps --version 查看来自 procps-ng 还是 busybox,精简镜像里的 busybox ps 对 -eo、--sort 这类参数支持不同,跑之前先用 ps --help 看一眼。二是所处的命名空间:在容器里读 /proc,看到的是容器视角的 PID,和处理机上 ps 看到的号不是一回事,需要结合 docker top 或宿主侧命令对照。三是这些内容会随发行版和工具版本变化,具体字段定义以本机 man ps、man top、man proc 的说明为准,不要照搬别处的输出样式。
查看进程的命令最容易搞错的一点
最常见的误解是把 ps aux | grep 关键字 的输出当成全部结果,却没意识到里面有一条是 grep 自己。它的命令行里包含了你输入的关键字,所以必然匹配上自己。在只跑一条、同名进程本该只有一个的场景里,这多出来的一条会让人误判“进程起了两份”,或者拿着 grep 的 PID 去 kill,结果什么都没停掉。
判断分界很清楚:那条记录的 PID,在两次独立执行之间会不会变?grep 自己的 PID 每次都不同,真正常驻的进程 PID 稳定。更省事的区分动作是直接改用不自匹配的写法:

ps -ef | grep '[n]ginx'
pgrep -a nginx
[n]ginx 这种方括号写法让 grep 进程自身的命令行里出现的是 [n]ginx 而不是 nginx,因此不会再匹配到自己;pgrep 默认就不会把自身算进去。如果两条命令给出的 PID 集合一致,说明之前看到的多余那条确实只是 grep。顺带记一个同类坑:进程 STAT 是 Z(僵尸)或 D(不可中断睡眠)时,kill -9 不生效,这不是权限问题,先看 /proc/<PID>/status 里的 State 再判断。
查看进程的命令:一个照着就能做完的做法
下面这条组合命令用于“按名字定位并按资源排序查看”,在执行机上直接粘贴即可,把 nginx 换成你要找的名字:
pgrep -a nginx
ps -eo pid,ppid,user,stat,etime,pcpu,pmem,args --sort=-pcpu | head -n 15
第一条应看到每行一个 PID 加完整命令行;如果没有任何输出,说明按这个名字找不到进程(也可能是名字与实际二进制不同,换 -f 再试)。第二条应看到占用最高的十五个进程,表头就是各列含义,args 列是完整命令行。拿到 PID 后按其执行:

- 确认身份:
ls -l /proc/<PID>/exe与tr '\0' ' ' < /proc/<PID>/cmdline; echo。应看到 exe 指向真实二进制路径,cmdline 拼成一条可读命令。 - 看状态和归属:
grep -E '^(Name|State|PPid|Uid|Threads)' /proc/<PID>/status。应看到 State 为 S(睡眠)、R(运行)等单字母加说明,PPid 指向它的父进程。 - 看线程与实时占用:
top -p <PID>,界面顶部是该 PID 的实时 CPU、内存;要按线程拆开用ps -L -p <PID> -o pid,tid,stat,pcpu,comm,应看到每个 TID 一行。 - 看它在哪、打开什么:
ls -l /proc/<PID>/cwd和ls -l /proc/<PID>/fd | head。 - 需要停止时先礼后兵:
kill -TERM <PID>,等待几秒用ps -p <PID> -o pid,stat,args复查,仍存在再kill -KILL <PID>。若 STAT 是 D,KILL 也无效,需要查 IO 或挂载侧原因。
如果进程由 systemd 托管,systemctl status 服务名 输出里的 Main PID 是权威来源,重启后号会变,不要拿旧 PID 做判断。
查看进程的命令:怎么验证结果对不对
验证分两种场景,判据都很直接。
场景一,只是查看、没有停止进程。用两种互相独立的途径交叉确认同一个 PID:ps -p <PID> -o pid,stat,etime,args 和 pgrep -a -f 关键字。正常结果是两者给出同一个 PID,且 args 里的命令一致。再对照 top -p <PID> 能正常显示该进程;如果 top 里找不到而 ps 里有,通常是 top 的刷新间隔内进程已切换,或者你所在的命名空间与 ps 不同。
场景二,停止进程之后。ps -p <PID> 无输出、退出码为 1,同时 ls /proc/<PID> 报 “No such file or directory”,两者同时满足才算真正退出。pgrep -a 名字 的返回行数相比操作前减少对应的数量,是另一个可核对的旁证。如果父进程会被 systemd、supervisor 或容器运行时自动拉起,短时间内可能又出现同名进程但 PID 不同,这属于预期行为,判断时要看 PID 而不是只看名字。