ps 命令全面详解

ps 命令全面详解

一、ps 命令基础

1. 什么是 ps?

  • 名称来源:Process Status(进程状态)
  • 功能:查看当前系统进程状态
  • 特点:显示进程信息快照(非实时)

2. 基本语法

复制代码
ps [选项]
ps --help all  # 查看所有选项

二、常用选项组合

1. 经典组合

复制代码
# 查看所有进程(BSD风格)
ps aux

# 查看所有进程(标准风格)
ps -ef

# 查看所有进程的完整信息
ps -eF
ps -ely

# 按CPU使用率排序
ps aux --sort=-%cpu | head -20

# 按内存使用率排序
ps aux --sort=-%mem | head -20

2. 选项详解:ps aux

复制代码
ps aux
# a: 显示所有用户的进程
# u: 以用户为主的格式显示
# x: 显示没有控制终端的进程(后台进程)

# 输出列说明:
USER    PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root      1  0.0  0.1 169020  9384 ?        Ss   Jan15   0:01 /sbin/init

3. 选项详解:ps -ef

复制代码
ps -ef
# -e: 显示所有进程
# -f: 完整格式显示

# 输出列说明:
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 Jan15 ?        00:00:01 /sbin/init

三、输出列含义详解

1. ps aux 输出列

复制代码
USER    : 进程所有者
PID     : 进程ID
%CPU    : CPU使用率百分比
%MEM    : 内存使用率百分比
VSZ     : 虚拟内存大小(KB)
RSS     : 实际物理内存大小(KB)
TTY     : 终端编号
        ? 表示与终端无关
        pts/0 表示伪终端
        tty1 表示控制台
STAT    : 进程状态(见下文详细解释)
START   : 进程启动时间
TIME    : 进程使用CPU总时间
COMMAND : 启动进程的命令

2. ps -ef 输出列

复制代码
UID     : 用户ID
PID     : 进程ID
PPID    : 父进程ID
C       : CPU使用率
STIME   : 启动时间
TTY     : 终端
TIME    : CPU时间
CMD     : 命令名(带参数)

3. 进程状态(STAT)详解

复制代码
# 基本状态:
R   运行 (Running/Runnable)
S   睡眠 (Sleeping),可中断
D   不可中断的睡眠(通常是I/O)
T   停止 (Stopped)
Z   僵尸 (Zombie)
X   死亡 (Dead)

# 附加标志:
<   高优先级
N   低优先级
L   有页面锁定在内存中
s   会话领导者 (Session leader)
l   多线程进程
+   在前台进程组

四、进程过滤和查找

1. 按用户过滤

复制代码
# 查看指定用户的进程
ps -u username
ps aux | grep username
ps -U root          # 按UID
ps -u $(id -u)      # 当前用户

# 查看多个用户
ps -u user1,user2
ps -U 1000,1001

2. 按进程名/命令过滤

复制代码
# 精确匹配进程名
ps -C nginx
ps -C java,nginx

# 使用grep查找
ps aux | grep nginx
ps -ef | grep [n]ginx      # 技巧:避免grep自身

# 按命令模式匹配
ps aux | grep -E "(nginx|apache)"
ps aux | awk '$11 ~ /nginx/'

3. 按PID/PPID过滤

复制代码
# 查看特定PID
ps -p 1234
ps -fp 1234          # 详细格式

# 查看多个PID
ps -p 1234,5678,9012

# 查看子进程
ps --ppid 1234       # PPID为1234的进程
ps -o pid,ppid,cmd --ppid 1234

# 查看进程树
ps -ef --forest      # 显示进程树
pstree               # 专用进程树命令

4. 按终端过滤

复制代码
# 查看特定终端的进程
ps -t tty1
ps -t pts/0

# 查看所有有终端的进程
ps -a

# 查看所有进程(包括无终端的)
ps -x

五、自定义输出格式

1. 使用 -o 选项自定义列

复制代码
# 自定义显示的列
ps -eo pid,ppid,user,comm,pcpu,pmem,etime
ps axo pid,user,pri,ni,cmd

# 常用字段:
pid     : 进程ID
ppid    : 父进程ID
user    : 用户名
comm    : 命令名(无参数)
cmd     : 完整命令行
pcpu    : CPU使用率
pmem    : 内存使用率
vsz     : 虚拟内存大小
rss     : 物理内存大小
tty     : 终端
stat    : 进程状态
time    : CPU时间
etime   : 进程运行时间
start   : 启动时间
nice    : 优先级值
pri     : 优先级
nlwp    : 线程数

2. 格式化输出

复制代码
# 添加标题
ps -eo pid,user,cmd --headers

# 自定义标题
ps -eo pid=进程ID,user=用户名,cmd=命令

# 更复杂的格式
ps -eo pid,user:20,cmd --sort=-pid

# 按指定顺序排列
ps -eo user,pid,pcpu,pmem,cmd --sort=user

3. 时间和日期格式

复制代码
# 不同时间格式
ps -eo pid,user,etime    # 运行时间 [[DD-]hh:]mm:ss
ps -eo pid,user,etimes   # 运行时间(秒)
ps -eo pid,user,lstart   # 启动具体时间
ps -eo pid,user,start    # 启动时间(简写)

# 示例:
ps -eo pid,user,etime,cmd | head -5
# PID   USER     ELAPSED CMD
# 1     root       2-03:15:01 /sbin/init
# 2     root       2-03:15:01 [kthreadd]

六、排序和统计

1. 排序进程

复制代码
# 按CPU使用率降序
ps aux --sort=-%cpu
ps -eo pid,pcpu,cmd --sort=-pcpu

# 按内存使用率降序
ps aux --sort=-%mem
ps -eo pid,pmem,cmd --sort=-pmem

# 按PID降序(最新进程)
ps aux --sort=-pid

# 按启动时间
ps aux --sort=start_time

# 多字段排序
ps aux --sort=-%cpu,-%mem

2. 统计信息

复制代码
# 统计进程数
ps -e | wc -l
ps aux | wc -l

# 按用户统计
ps -eo user=| sort | uniq -c | sort -rn

# 按命令统计
ps -eo comm=| sort | uniq -c | sort -rn

# 统计线程数
ps -eo nlwp | awk '{sum+=$1} END {print sum}'

# 统计内存使用
ps -eo rss=| awk '{sum+=$1} END {print sum " KB"}'

七、进程间关系

1. 查看进程树

复制代码
# 显示进程树
ps -ejH          # 缩进显示层级
ps axjf          # 类似pstree的显示
ps -e --forest   # ASCII树状图

# 显示特定进程的树
ps -f --forest --ppid 1234
ps --forest -C nginx

2. 查看进程组和会话

复制代码
# 查看进程组
ps -o pid,pgid,cmd
ps -ej | grep -E "PID|1234"  # 查看特定进程组

# 查看会话
ps -o pid,sid,cmd
ps -efj | head -20          # 显示PID, PGID, SID

# 查看孤儿进程(PPID=1)
ps -eo pid,ppid,cmd | awk '$2==1'

3. 查看线程

复制代码
# 查看线程(LWP - Light Weight Process)
ps -eLf          # 显示所有线程
ps -T -p 1234    # 查看特定进程的线程

# 线程相关字段
lwp     : 线程ID
nlwp    : 线程数
spid    : 线程ID(Solaris风格)

# 统计线程数最多的进程
ps -eo pid,nlwp,cmd --sort=-nlwp | head -10

八、系统监控相关

1. 实时监控进程

复制代码
# 使用watch配合ps
watch -n 1 'ps aux --sort=-%cpu | head -20'
watch -n 2 'ps -eo pid,user,pcpu,pmem,cmd --sort=-pcpu | head -10'

# 监控特定进程
watch -n 1 'ps -p 1234 -o pid,pcpu,pmem,vsz,rss,etime'

# 结合top(更适合实时监控)
top
htop    # 增强版top

2. 资源使用监控

复制代码
# 查看CPU使用最高的进程
ps -eo pid,user,pcpu,cmd --sort=-pcpu | head -10

# 查看内存使用最高的进程
ps -eo pid,user,pmem,rss,cmd --sort=-pmem | head -10

# 查看虚拟内存使用
ps -eo pid,user,vsz,cmd --sort=-vsz | head -10

# 查看I/O等待
ps -eo pid,user,stat,cmd | grep "D"

3. 检测异常进程

复制代码
# 查找僵尸进程
ps aux | grep 'Z'
ps -eo pid,stat,cmd | grep -E "^[0-9]+ Z"

# 查找CPU使用异常的进程
ps -eo pid,user,pcpu,cmd | awk '$3>50 {print}'

# 查找内存泄漏嫌疑进程(RSS持续增长)
# 需要多次采样比较
ps -eo pid,user,rss,cmd | sort -k3 -n | tail -10

九、实际应用场景

1. 故障排查

复制代码
# 查找占用CPU过高的进程
ps aux --sort=-%cpu | head -10

# 查找占用内存过高的进程
ps aux --sort=-%mem | head -10

# 查找死锁或挂起的进程
ps aux | grep -E "(D|T)"

# 检查服务是否运行
ps -ef | grep -E "(nginx|mysql|redis)" | grep -v grep

2. 系统维护

复制代码
# 生成进程快照(用于比较)
ps -eo pid,user,pcpu,pmem,cmd > /tmp/process_snapshot_$(date +%Y%m%d).txt

# 清理僵尸进程
ps -eo pid,stat | grep 'Z' | awk '{print $1}' | xargs kill -9

# 检查进程启动时间(判断是否重启过)
ps -eo pid,user,lstart,cmd | grep -E "(nginx|apache)"

3. 安全审计

复制代码
# 检查异常网络进程
ps -eo pid,user,cmd | grep -E "(nc|telnet|ssh|socat)"

# 检查隐藏进程(无名或无命令行)
ps -eo pid,user,cmd | grep -E "^[0-9]+ [^ ]+ $"

# 检查特权进程
ps -eo pid,user,euid,ruid,cmd | awk '$3==0 || $4==0'

# 检查setuid/setgid进程
ps -eo pid,user,cmd | xargs ls -l 2>/dev/null | grep -E "^...s|^......s"

4. 容器环境

复制代码
# Docker容器内查看进程
docker exec container_name ps aux

# Kubernetes Pod中查看进程
kubectl exec pod-name -- ps aux

# 查看所有容器的进程
docker ps -q | xargs -I {} docker exec {} ps aux

十、高级技巧和脚本

1. 进程监控脚本

复制代码
#!/bin/bash
# process_monitor.sh

LOG_FILE="/var/log/process_monitor.log"
THRESHOLD_CPU=80
THRESHOLD_MEM=50
CHECK_INTERVAL=5

monitor_processes() {
    while true; do
        echo "=== $(date) ===" >> "$LOG_FILE"
        
        # 检查高CPU进程
        ps -eo pid,user,pcpu,pmem,cmd --sort=-pcpu | \
            awk -v threshold="$THRESHOLD_CPU" 'NR>1 && $3>threshold' >> "$LOG_FILE"
        
        # 检查高内存进程
        ps -eo pid,user,pcpu,pmem,cmd --sort=-pmem | \
            awk -v threshold="$THRESHOLD_MEM" 'NR>1 && $4>threshold' >> "$LOG_FILE"
        
        # 检查僵尸进程
        zombie_count=$(ps aux | grep -c 'Z')
        if [ "$zombie_count" -gt 0 ]; then
            echo "发现 $zombie_count 个僵尸进程:" >> "$LOG_FILE"
            ps aux | grep 'Z' >> "$LOG_FILE"
        fi
        
        sleep "$CHECK_INTERVAL"
    done
}

# 运行监控
monitor_processes

2. 进程信息收集脚本

复制代码
#!/bin/bash
# process_info_collector.sh

OUTPUT_DIR="/tmp/process_info_$(date +%Y%m%d_%H%M%S)"
mkdir -p "$OUTPUT_DIR"

collect_info() {
    echo "收集进程信息到: $OUTPUT_DIR"
    
    # 1. 所有进程列表
    ps aux > "$OUTPUT_DIR/ps_aux.txt"
    
    # 2. 进程树
    ps -ejH > "$OUTPUT_DIR/process_tree.txt"
    
    # 3. 按用户分组
    ps -eo user,pid,pcpu,pmem,cmd --sort=user > "$OUTPUT_DIR/by_user.txt"
    
    # 4. 线程信息
    ps -eLf > "$OUTPUT_DIR/threads.txt"
    
    # 5. 网络相关进程
    ps -eo pid,user,cmd | grep -E "(ssh|nginx|apache|mysql|redis)" > "$OUTPUT_DIR/network_processes.txt"
    
    # 6. 统计信息
    {
        echo "总进程数: $(ps -e | wc -l)"
        echo "总线程数: $(ps -eL | wc -l)"
        echo "按用户统计:"
        ps -eo user=| sort | uniq -c | sort -rn
        echo -e "\n按命令统计:"
        ps -eo comm=| sort | uniq -c | sort -rn | head -20
    } > "$OUTPUT_DIR/statistics.txt"
    
    echo "收集完成"
}

collect_info

3. 自动清理僵尸进程

复制代码
#!/bin/bash
# zombie_cleaner.sh

MAX_ZOMBIES=10
LOG_FILE="/var/log/zombie_clean.log"

clean_zombies() {
    zombie_count=$(ps aux | grep -c 'Z')
    
    if [ "$zombie_count" -eq 0 ]; then
        echo "$(date): 未发现僵尸进程" >> "$LOG_FILE"
        return 0
    fi
    
    if [ "$zombie_count" -gt "$MAX_ZOMBIES" ]; then
        echo "$(date): 警告!发现 $zombie_count 个僵尸进程" >> "$LOG_FILE"
        
        # 列出僵尸进程
        ps aux | grep 'Z' >> "$LOG_FILE"
        
        # 尝试清理(谨慎操作)
        for pid in $(ps -eo pid,stat | awk '$2=="Z" {print $1}'); do
            parent_pid=$(ps -o ppid= -p "$pid" 2>/dev/null | tr -d ' ')
            
            if [ -n "$parent_pid" ]; then
                echo "$(date): 尝试向父进程 $parent_pid 发送SIGCHLD" >> "$LOG_FILE"
                kill -s SIGCHLD "$parent_pid"
                sleep 1
                
                # 检查是否还存在
                if ps -p "$pid" > /dev/null 2>&1; then
                    echo "$(date): 进程 $pid 仍然存在,尝试强制终止" >> "$LOG_FILE"
                    kill -9 "$pid"
                fi
            fi
        done
    else
        echo "$(date): 发现 $zombie_count 个僵尸进程(在阈值内)" >> "$LOG_FILE"
    fi
}

# 可以加入crontab定期执行
clean_zombies

十一、ps 与其他命令配合

1. 与 grep 配合

复制代码
# 查找特定进程
ps aux | grep nginx
ps -ef | grep [n]ginx              # 技巧:避免显示grep自身
ps aux | grep -E "(nginx|mysql)"   # 多个模式

# 排除特定进程
ps aux | grep nginx | grep -v grep
ps aux | grep -v "pts/"            # 排除终端进程

2. 与 awk 配合

复制代码
# 提取特定字段
ps aux | awk '{print $1, $2, $11}'          # 用户,PID,命令
ps aux | awk '$1=="root" {print $0}'        # root用户的进程
ps aux | awk '$3>10 {print $2, $3, $11}'    # CPU>10%的进程

# 计算统计
ps aux | awk 'NR>1 {sum+=$3} END {print "总CPU:", sum"%"}' 
ps aux | awk '{mem[$1]+=$4} END {for(u in mem) print u, mem[u]"%"}' 

3. 与 sort/uniq 配合

复制代码
# 按用户统计进程数
ps aux | awk '{print $1}' | sort | uniq -c | sort -rn

# 按命令统计
ps aux | awk '{print $11}' | sort | uniq -c | sort -rn | head -10

# 按CPU排序
ps aux | sort -k3 -rn | head -10

4. 与 xargs 配合

复制代码
# 批量操作进程
ps aux | grep chrome | awk '{print $2}' | xargs kill
ps -eo pid,cmd | grep python | awk '{print $1}' | xargs -I {} kill -9 {}

# 批量获取进程信息
ps aux | grep nginx | awk '{print $2}' | xargs -I {} ps -p {} -o pid,user,pcpu,pmem

十二、不同系统的差异

1. Linux 各发行版

复制代码
# 大多数Linux发行版支持GNU ps
ps --version  # 查看版本

# 主要选项风格:
# 1. UNIX风格:选项前带 - (ps -ef)
# 2. BSD风格:选项前不带 - (ps aux)
# 3. GNU风格:长选项 (ps --pid 1234)

# 常用组合在各个发行版都有效
ps aux    # BSD风格,广泛支持
ps -ef    # UNIX风格,广泛支持

2. macOS (BSD 风格)

复制代码
# macOS使用BSD ps,与Linux有些差异
ps aux    # 可用,类似Linux
ps -ef    # 不可用,用 ps -e -f 代替

# macOS特有选项
ps -ax    # 显示所有进程
ps -U username  # 按用户
ps -p pid      # 按PID

# 查看线程
ps -M -p pid   # 显示线程

3. 兼容性写法

复制代码
# 跨平台兼容的写法
ps -e -f    # 替代 ps -ef
ps a u x    # 替代 ps aux(分开写)

# 检查僵尸进程(跨平台)
ps -o pid,state,command | grep 'Z'

十三、性能优化技巧

1. 减少输出数据量

复制代码
# 只选择需要的列
ps -o pid,pcpu,cmd   # 只显示3列,而不是所有列

# 限制行数
ps aux | head -20
ps -eo pid,user,cmd --sort=-pcpu | head -10

# 使用特定条件过滤
ps -C nginx -o pid,user,pcpu  # 只查nginx进程

2. 避免不必要的排序

复制代码
# 如果需要排序,在ps内部完成
ps -eo pid,pcpu,cmd --sort=-pcpu  # 高效

# 避免通过管道多次排序
ps aux | sort -k3 -rn | head -10  # 可能低效

3. 使用缓存(如果频繁查询)

复制代码
# 对于监控脚本,可以考虑缓存
CACHE_FILE="/tmp/ps_cache"
CACHE_TIME=5  # 秒

if [ -f "$CACHE_FILE" ]; then
    cache_age=$(($(date +%s) - $(stat -c %Y "$CACHE_FILE")))
    if [ "$cache_age" -lt "$CACHE_TIME" ]; then
        cat "$CACHE_FILE"
        exit 0
    fi
fi

ps aux --sort=-%cpu | head -20 > "$CACHE_FILE"
cat "$CACHE_FILE"

十四、常见问题排查

1. 进程卡住或挂起

复制代码
# 查看进程状态
ps aux | grep -E "(D|T)"  # D=不可中断睡眠,T=停止

# 查看进程等待什么
ps -eo pid,stat,wchan,cmd | grep -E " D| T"

# 检查进程打开的文件
lsof -p PID

2. 内存泄漏检测

复制代码
# 监控进程内存增长
watch -n 1 'ps -p 1234 -o pid,rss,cmd'

# 记录内存变化
while true; do
    ps -p 1234 -o pid,rss,etime >> /tmp/memory_log.txt
    sleep 60
done

3. CPU 使用异常

复制代码
# 查看占用CPU高的进程
ps aux --sort=-%cpu | head -10

# 查看进程的CPU时间
ps -eo pid,user,time,cmd --sort=-time | head -10

# 查看进程优先级
ps -eo pid,user,nice,pri,cmd | grep -E "(PID|1234)"

十五、总结速查表

常用命令速查

复制代码
# 查看所有进程
ps aux          # BSD风格(最常用)
ps -ef          # UNIX风格
ps -eF          # 完整格式
ps -ely         # 长格式

# 查看特定进程
ps -p PID       # 按PID
ps -U user      # 按用户
ps -C command   # 按命令名

# 查看进程树
ps -ejH         # 缩进显示
ps axjf         # 树状图
ps --forest     # ASCII树

# 查看线程
ps -eLf         # 所有线程
ps -T -p PID    # 特定进程线程

# 自定义输出
ps -eo pid,user,pcpu,pmem,cmd
ps -o pid=进程ID,user=用户名,cmd=命令

# 排序
ps aux --sort=-%cpu     # 按CPU降序
ps aux --sort=-%mem     # 按内存降序

关键字段含义

复制代码
PID     : 进程ID
PPID    : 父进程ID
USER    : 进程所有者
%CPU    : CPU使用率
%MEM    : 内存使用率
VSZ     : 虚拟内存大小
RSS     : 物理内存大小
TTY     : 控制终端
STAT    : 进程状态
START   : 启动时间
TIME    : CPU时间
COMMAND : 命令

进程状态码

复制代码
R   运行/可运行
S   可中断睡眠
D   不可中断睡眠
T   已停止
Z   僵尸进程
X   死亡进程

附加标志:
<   高优先级
N   低优先级
L   内存锁定
s   会话领导
l   多线程
+   前台进程组

最佳实践

  1. 故障排查 :先用 ps aux | head -20 快速查看
  2. 精确查找 :使用 ps -Cps -p 而不是 grep
  3. 监控 :使用 watch 配合 ps 进行实时监控
  4. 脚本中 :使用 -o 指定精确字段,避免解析问题
  5. 性能:避免不必要的排序和全量输出

记住ps 是进程管理的瑞士军刀,熟练掌握它对于系统管理和故障排查至关重要!

相关推荐
Heavydrink31 分钟前
Java项目部署云服务器详细教程
java·服务器·开发语言
Lethehong33 分钟前
算力新标杆:昇腾Atlas 800T NPU实战Llama-2-7b全流程评测与技术解析
运维·服务器·数据库·llama-2-7b·昇腾atlas 800t
wanhengidc36 分钟前
云手机中都运用到了哪些技术
运维·服务器·科技·智能手机·云计算
wgego38 分钟前
http协议中各个网段含义
网络·网络协议·http
soft200152539 分钟前
Linux + MySQL + Sysbench 一键部署和压测教程
linux·mysql·adb
漫漫求40 分钟前
2、Ubuntu 22.04 安装px4 1.14:快速搭建
linux·运维·ubuntu
阑梦清川40 分钟前
计算机网络--关于域名服务器的访问顺序
运维·服务器·计算机网络
张太行_40 分钟前
TCP连接长时间未进行数据交互是否会断开?如何维持?
网络·tcp/ip·智能路由器
栈低来信44 分钟前
Linux侵入式链表详解
linux·链表