ps 是什么
ps(process status)读取 Linux 的 /proc 虚拟文件系统,把某一瞬间的进程表打印出来,属于一次性快照工具:打印完立即退出,不会刷新。持续刷新的监控交给 top/htop。应急排查里它解决三个问题——谁在跑、什么时候起来的、完整命令行是什么。所有 Linux 发行版都自带(procps-ng 包提供),macOS 与 BSD 同样内置,但选项风格与 Linux 有差异。
基本信息
| 适用平台 | Linux(procps-ng)、macOS、BSD 及多数 Unix |
|---|---|
| BSD 风格写法 | ps auxww:a 全部用户、u 面向用户格式、x 含无终端进程、ww 不截断宽度 |
| UNIX 风格写法 | ps -ef 或 ps -eo pid,ppid,user,lstart,etime,cmd |
| 排序选项 | --sort=start_time 按启动时间;--sort=-pcpu 按 CPU 降序 |
| 权限要求 | 查看自己名下的进程无需特权;/proc 若以 hidepid=2 挂载,非 root 只能看到自己的进程 |
| 实时性 | 单次快照,需要连续观察时用 top 或写循环采样 |
典型使用场景
- CPU 或负载告警时确认到底是哪个进程吃满核心,先看资源再谈清理
- 按启动时间倒序列出最近起来的进程,与入侵告警时间点对齐
- 看 PPID 判断进程是被人手工执行的、还是被 cron/systemd 拉起的
- 拿到 PID 后进 /proc/<PID> 看 exe、cwd、environ 做进一步取证
- 清理木马前确认目标进程与父子关系,决定 kill 的先后顺序
- 新接手一台机器时做全量进程基线,便于日后对比
常用示例
常用示例
ps auxww | head -n 30 # 全量进程,命令行不截断
ps -ef | grep -v grep | grep -i ssh # UNIX 风格写法加关键字过滤
ps -eo pid,ppid,user,lstart,cmd --sort=start_time | tail -n 20 # 最近启动的 20 个进程
ps -eo pid,ppid,pcpu,pmem,stat,cmd --sort=-pcpu | head -n 10 # CPU 占用前 10
ps -o pid,ppid,cmd -p 1234 # 只看指定 PID 的父子与命令
ps -L -p 1234 # 查看该进程的线程列表
ls -d /proc/[0-9]* | wc -l # 内核进程目录数,与 ps 行数对比
while true; do ps -eo pid,lstart,cmd | tail -n 5; sleep 2; done # 循环采样抓短命进程输出逐列读法
| 列 | 含义 | 异常信号 |
|---|---|---|
| USER | 进程属主 | Web 或数据库相关进程跑在 nobody、未知账号名下 |
| PID / PPID | 进程号与父进程号 | PPID 为 1 的孤儿进程;父子进程名字完全对不上 |
| %CPU / %MEM | CPU 与内存占用百分比 | 长期贴近 100%,而命令名是 kworker 之类系统名 |
| VSZ / RSS | 虚拟内存与常驻内存 | RSS 远超二进制体积,提示可能有注入或内存马 |
| TTY | 关联的终端设备 | 显示问号说明没有终端,守护进程和后门都这样启动 |
| STAT | 进程状态与附加标志 | D 长时间不退说明卡在 IO;Z 是僵尸;T 是被停止 |
| START / TIME | 启动时间与累计 CPU 时间 | 启动时间与告警时间吻合的进程最该优先看 |
| COMMAND | 完整命令行 | 路径落在 /tmp、/dev/shm,或含 base64 解码、curl 管道执行 |
STAT 常见取值:R 运行、S 可中断睡眠、D 不可中断睡眠、T 被停止或被跟踪、Z 僵尸;附加标志有 s 会话首进程、l 多线程、+ 前台进程组、< 高优先级。看到 D 状态先查磁盘与网络存储是否卡住,不要直接 kill -9。
ps 的输出可能被 rootkit 过滤,ps 二进制本身也可能已被替换。用 ls -d /proc/[0-9]* 统计进程目录数与 ps 行数对比,差得多就用静态编译的 busybox ps 复核,别只信 ps。
可疑进程交叉验证
可疑进程交叉验证
ps auxww | grep -viE 'grep' | grep -iE 'tmp|shm|curl|wget|base64|python -c' # 关键词过筛
sudo ls -l /proc/1234/exe /proc/1234/cwd # 真实可执行文件与工作目录
sudo cat /proc/1234/environ | tr '\0' '\n' | head # 进程环境变量
docker top <容器名> # 容器内进程(在宿主机执行 ps 看不到容器内视角)容器与 PID 命名空间:在容器里执行 ps 只能看到本命名空间内的进程,看不到宿主机其他容器;反过来在宿主机执行 ps 能看到所有容器进程,因此排查容器被投毒要先登宿主机。