Linux查看进程的命令

文章导读
在 Linux 上查进程,多数时候要回答的只有四个问题:进程还在不在、PID 是多少、谁启动的、占了多少 CPU 和内存。能直接回答这些的是 ps、pgrep、top,以及 /proc/<PID>/ 下的几个文件;先跑哪条,取决于你要的是一次性快照,还是持续观察。
📋 目录
  1. Ⅰ 查看进程的命令:先把能核对的事实摆清楚
  2. Ⅱ 查看进程的命令最容易搞错的一点
  3. Ⅲ 查看进程的命令:一个照着就能做完的做法
  4. Ⅳ 查看进程的命令:怎么验证结果对不对
A A

在 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 稳定。更省事的区分动作是直接改用不自匹配的写法:

Linux查看进程的命令
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 后按其执行:

Linux查看进程的命令
  1. 确认身份:ls -l /proc/<PID>/exe 与 tr '\0' ' ' < /proc/<PID>/cmdline; echo。应看到 exe 指向真实二进制路径,cmdline 拼成一条可读命令。
  2. 看状态和归属:grep -E '^(Name|State|PPid|Uid|Threads)' /proc/<PID>/status。应看到 State 为 S(睡眠)、R(运行)等单字母加说明,PPid 指向它的父进程。
  3. 看线程与实时占用:top -p <PID>,界面顶部是该 PID 的实时 CPU、内存;要按线程拆开用 ps -L -p <PID> -o pid,tid,stat,pcpu,comm,应看到每个 TID 一行。
  4. 看它在哪、打开什么:ls -l /proc/<PID>/cwd 和 ls -l /proc/<PID>/fd | head。
  5. 需要停止时先礼后兵: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 而不是只看名字。