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 多线程
+ 前台进程组
最佳实践
- 故障排查 :先用
ps aux | head -20快速查看 - 精确查找 :使用
ps -C或ps -p而不是grep - 监控 :使用
watch配合ps进行实时监控 - 脚本中 :使用
-o指定精确字段,避免解析问题 - 性能:避免不必要的排序和全量输出
记住 :ps 是进程管理的瑞士军刀,熟练掌握它对于系统管理和故障排查至关重要!