ps 命令详解#
ps(Process Status)是 Linux 系统中用于查看当前运行进程状态的命令。它可以显示进程的详细信息,包括 PID、CPU 使用率、内存使用、运行时间等,是系统管理员和开发人员进行进程管理和故障排查的重要工具。
入门#
基本用法#
# 查看当前用户的进程
ps
# 查看所有进程
ps -e
# 查看所有进程(包括其他用户)
ps -a
# 查看所有进程的详细信息
ps -aux
# 查看特定进程
ps -p 1234常用选项#
| 选项 | 说明 |
|---|---|
-a | 显示所有终端的进程 |
-e | 显示所有进程 |
-f | 显示完整格式 |
-u | 显示用户导向的格式 |
-x | 显示没有控制终端的进程 |
-p | 指定进程 ID |
-C | 指定命令名 |
-t | 指定终端 |
基本示例#
# 查看当前用户的进程
ps
# 输出示例:
# PID TTY TIME CMD
# 1234 pts/0 00:00:01 bash
# 5678 pts/0 00:00:00 ps
# 查看所有进程
ps -e
# 查看所有进程的详细信息
ps -aux
# 输出示例:
# USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
# root 1 0.0 0.1 21568 1234 ? Ss 10:00 0:01 /sbin/init
# root 1234 0.0 0.2 34567 2345 ? S 10:00 0:00 /usr/sbin/nginx
# mysql 5678 0.5 2.3 123456 56789 ? Sl 10:00 0:05 /usr/sbin/mysqld中级#
进程筛选#
# 查看特定用户的进程
ps -u username
# 查看特定用户的进程(包括所有用户)
ps -u username -u root
# 查看特定进程名的进程
ps -C nginx
# 查看特定 PID 的进程
ps -p 1234
# 查看多个 PID 的进程
ps -p 1234,5678,9012
# 查看特定终端的进程
ps -t pts/0进程排序#
# 按 CPU 使用率排序
ps -aux --sort=-%cpu
# 按内存使用排序
ps -aux --sort=-%mem
# 按运行时间排序
ps -aux --sort=-etime
# 按进程 ID 排序
ps -aux --sort=pid
# 组合排序(先按 CPU,再按内存)
ps -aux --sort=-%cpu,-%mem进程状态#
# 查看所有进程的状态
ps -eo stat,cmd
# 查看特定状态的进程
ps -eo stat,cmd | grep "^R"
# 查看僵尸进程
ps -eo stat,cmd | grep "^Z"
# 查看睡眠进程
ps -eo stat,cmd | grep "^S"
# 查看停止的进程
ps -eo stat,cmd | grep "^T"高级#
高级筛选#
# 查看特定用户的进程(完整格式)
ps -u username -f
# 查看特定进程的完整命令行
ps -p 1234 -f
# 查看所有进程的完整格式
ps -ef
# 查看进程树
ps -ejH
# 查看进程的线程
ps -eLf
# 查看进程的安全上下文
ps -eZ自定义输出#
# 自定义输出字段
ps -eo pid,ppid,user,%cpu,%mem,cmd
# 查看进程的父进程
ps -eo pid,ppid,cmd
# 查看进程的启动时间
ps -eo pid,lstart,cmd
# 查看进程的运行时间
ps -eo pid,etime,cmd
# 查看进程的优先级
ps -eo pid,ni,pri,cmd
# 查看进程的内存使用
ps -eo pid,vsz,rss,%mem,cmd进程树#
# 查看进程树
ps -ejH
# 查看进程树(ASCII 字符)
ps -ejH --forest
# 查看特定用户的进程树
ps -u username -ejH
# 查看特定进程的进程树
ps -p 1234 -ejH
# 查看进程树(完整格式)
ps -ef --forest大师#
进程监控脚本#
#!/bin/bash
# 进程监控脚本
PROCESS_NAME=$1
LOG_FILE="process_monitor.log"
# 监控进程状态
monitor_process() {
local process_name=$1
while true; do
local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
local pid=$(pgrep -o "$process_name")
if [ -n "$pid" ]; then
local cpu_usage=$(ps -p $pid -o %cpu --no-headers)
local mem_usage=$(ps -p $pid -o %mem --no-headers)
local runtime=$(ps -p $pid -o etime --no-headers)
echo "$timestamp - PID: $pid, CPU: ${cpu_usage}%, MEM: ${mem_usage}%, Runtime: $runtime" >> $LOG_FILE
else
echo "$timestamp - Process $process_name not found" >> $LOG_FILE
fi
sleep 60
done
}
# 查找高资源使用进程
find_high_usage_processes() {
local metric=$1
local threshold=$2
case "$metric" in
cpu)
ps -eo pid,user,%cpu,cmd --sort=-%cpu | awk -v threshold=$threshold 'NR>1 && $3 > threshold {print $0}'
;;
mem)
ps -eo pid,user,%mem,cmd --sort=-%mem | awk -v threshold=$threshold 'NR>1 && $3 > threshold {print $0}'
;;
*)
echo "Invalid metric: $metric"
return 1
;;
esac
}
# 生成进程报告
generate_process_report() {
local report_file="process_report_$(date +%Y%m%d_%H%M%S).txt"
echo "Process Report - $(date)" > $report_file
echo "==================" >> $report_file
echo "" >> $report_file
echo "Top 10 CPU consuming processes:" >> $report_file
ps -eo pid,user,%cpu,%mem,cmd --sort=-%cpu | head -11 >> $report_file
echo "" >> $report_file
echo "Top 10 Memory consuming processes:" >> $report_file
ps -eo pid,user,%cpu,%mem,cmd --sort=-%mem | head -11 >> $report_file
echo "" >> $report_file
echo "Top 10 Longest running processes:" >> $report_file
ps -eo pid,user,etime,cmd --sort=-etime | head -11 >> $report_file
echo "Report saved to: $report_file"
}
# 主函数
main() {
case "$1" in
monitor)
monitor_process "$2"
;;
find)
find_high_usage_processes "$2" "$3"
;;
report)
generate_process_report
;;
*)
echo "Usage: $0 {monitor|find|report}"
exit 1
;;
esac
}
main "$@"批量进程管理#
#!/bin/bash
# 批量进程管理脚本
# 查找并显示进程
find_processes() {
local pattern=$1
echo "Searching for processes matching: $pattern"
ps -ef | grep "$pattern" | grep -v grep
}
# 查找特定用户的进程
find_user_processes() {
local username=$1
echo "Finding processes for user: $username"
ps -u $username -f
}
# 查找特定进程名的进程
find_named_processes() {
local process_name=$1
echo "Finding processes with name: $process_name"
ps -C $process_name -f
}
# 查找僵尸进程
find_zombie_processes() {
echo "Finding zombie processes"
ps -eo stat,pid,cmd | grep "^Z"
}
# 查找孤儿进程
find_orphan_processes() {
echo "Finding orphan processes"
ps -eo pid,ppid,cmd | awk '$2 == 1 {print $0}'
}
# 查找特定状态的进程
find_state_processes() {
local state=$1
echo "Finding processes in state: $state"
ps -eo stat,pid,cmd | grep "^$state"
}
# 生成进程统计
generate_statistics() {
echo "=== Process Statistics ==="
echo ""
# 总进程数
local total_processes=$(ps -e | wc -l)
echo "Total processes: $total_processes"
# 运行中的进程
local running_processes=$(ps -eo stat | grep "^R" | wc -l)
echo "Running processes: $running_processes"
# 睡眠进程
local sleeping_processes=$(ps -eo stat | grep "^S" | wc -l)
echo "Sleeping processes: $sleeping_processes"
# 僵尸进程
local zombie_processes=$(ps -eo stat | grep "^Z" | wc -l)
echo "Zombie processes: $zombie_processes"
# 停止的进程
local stopped_processes=$(ps -eo stat | grep "^T" | wc -l)
echo "Stopped processes: $stopped_processes"
}
# 主函数
main() {
case "$1" in
find)
find_processes "$2"
;;
user)
find_user_processes "$2"
;;
name)
find_named_processes "$2"
;;
zombie)
find_zombie_processes
;;
orphan)
find_orphan_processes
;;
state)
find_state_processes "$2"
;;
stats)
generate_statistics
;;
*)
echo "Usage: $0 {find|user|name|zombie|orphan|state|stats}"
exit 1
;;
esac
}
main "$@"进程关系分析#
#!/bin/bash
# 进程关系分析脚本
# 查看进程树
show_process_tree() {
local pid=${1:-1}
echo "Process Tree for PID: $pid"
ps -p $pid -f
echo ""
echo "Child Processes:"
ps -eo pid,ppid,cmd | awk -v parent=$pid '$2 == parent {print $0}'
}
# 查看进程的完整关系
show_full_process_tree() {
local pid=${1:-1}
echo "Full Process Tree for PID: $pid"
ps -ejH | grep -A 100 " $pid "
}
# 查看进程的父进程
show_parent_process() {
local pid=$1
local ppid=$(ps -p $pid -o ppid --no-headers)
echo "Parent Process of PID $pid:"
ps -p $ppid -f
}
# 查看进程的所有子进程
show_child_processes() {
local pid=$1
echo "Child Processes of PID $pid:"
ps -eo pid,ppid,cmd | awk -v parent=$pid '$2 == parent {print $0}'
}
# 查看进程的完整家族
show_process_family() {
local pid=$1
echo "=== Process Family for PID: $pid ==="
echo ""
# 父进程
echo "Parent Process:"
show_parent_process $pid
echo ""
# 子进程
echo "Child Processes:"
show_child_processes $pid
echo ""
# 进程树
echo "Process Tree:"
show_process_tree $pid
}
# 分析进程依赖
analyze_process_dependencies() {
local pid=$1
echo "=== Process Dependencies for PID: $pid ==="
echo ""
# 打开的文件
echo "Open Files:"
lsof -p $pid 2>/dev/null | head -10
echo ""
# 网络连接
echo "Network Connections:"
netstat -p 2>/dev/null | grep $pid | head -10
echo ""
# 内存映射
echo "Memory Maps:"
cat /proc/$pid/maps 2>/dev/null | head -10
}
# 主函数
main() {
case "$1" in
tree)
show_process_tree "$2"
;;
full-tree)
show_full_process_tree "$2"
;;
parent)
show_parent_process "$2"
;;
child)
show_child_processes "$2"
;;
family)
show_process_family "$2"
;;
dependencies)
analyze_process_dependencies "$2"
;;
*)
echo "Usage: $0 {tree|full-tree|parent|child|family|dependencies}"
exit 1
;;
esac
}
main "$@"无敌#
企业级进程管理系统#
#!/bin/bash
# 企业级进程管理系统
CONFIG_FILE="/etc/process_manager/config.conf"
LOG_DIR="/var/log/process_manager"
STATE_DIR="/var/run/process_manager"
mkdir -p $LOG_DIR $STATE_DIR
# 加载配置
source $CONFIG_FILE
# 初始化进程监控
init_process_monitor() {
local process_name=$1
local state_file="$STATE_DIR/${process_name}.state"
local pid=$(pgrep -o "$process_name")
if [ -n "$pid" ]; then
echo "$pid" > $state_file
log_message "$process_name initialized with PID: $pid"
else
echo "0" > $state_file
log_message "$process_name not found"
fi
}
# 监控进程状态
monitor_process() {
local process_name=$1
local state_file="$STATE_DIR/${process_name}.state"
while true; do
local current_pid=$(pgrep -o "$process_name")
local saved_pid=$(cat $state_file)
if [ "$current_pid" != "$saved_pid" ]; then
log_message "Process $process_name PID changed: $saved_pid -> $current_pid"
if [ -n "$current_pid" ]; then
echo "$current_pid" > $state_file
log_message "$process_name is now running with PID: $current_pid"
else
log_message "ALERT: Process $process_name stopped"
# 尝试重启
if [ "$AUTO_RESTART" = "true" ]; then
log_message "Attempting to restart $process_name..."
systemctl restart $process_name
if [ $? -eq 0 ]; then
local new_pid=$(pgrep -o "$process_name")
echo "$new_pid" > $state_file
log_message "$process_name restarted with PID: $new_pid"
else
log_message "ERROR: Failed to restart $process_name"
send_alert "Process $process_name failed to restart"
fi
fi
fi
fi
# 检查进程资源使用
if [ -n "$current_pid" ]; then
check_process_resources $process_name $current_pid
fi
sleep $MONITOR_INTERVAL
done
}
# 检查进程资源使用
check_process_resources() {
local process_name=$1
local pid=$2
local cpu_usage=$(ps -p $pid -o %cpu --no-headers)
local mem_usage=$(ps -p $pid -o %mem --no-headers)
if (( $(echo "$cpu_usage > $CPU_THRESHOLD" | bc -l) )); then
log_message "ALERT: $process_name CPU usage high: ${cpu_usage}%"
fi
if (( $(echo "$mem_usage > $MEMORY_THRESHOLD" | bc -l) )); then
log_message "ALERT: $process_name memory usage high: ${mem_usage}%"
fi
}
# 记录日志
log_message() {
local message=$1
local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
echo "[$timestamp] $message" >> $LOG_DIR/manager.log
}
# 发送告警
send_alert() {
local message=$1
if [ "$ENABLE_EMAIL_ALERTS" = "true" ]; then
echo "$message" | mail -s "Process Manager Alert" $ALERT_EMAIL
fi
if [ "$ENABLE_SLACK_ALERTS" = "true" ]; then
curl -X POST -H 'Content-type: application/json' --data "{\"text\":\"$message\"}" $SLACK_WEBHOOK
fi
}
# 生成监控报告
generate_monitor_report() {
local report_file="$LOG_DIR/monitor_report_$(date +%Y%m%d).txt"
echo "Process Monitor Report - $(date +%Y-%m-%d)" > $report_file
echo "=========================" >> $report_file
echo "" >> $report_file
for process_name in "${MONITORED_PROCESSES[@]}"; do
echo "=== $process_name ===" >> $report_file
local pid=$(pgrep -o "$process_name")
if [ -n "$pid" ]; then
ps -p $pid -f >> $report_file
else
echo "Process not running" >> $report_file
fi
echo "" >> $report_file
done
log_message "Monitor report generated: $report_file"
}
# 主程序
main() {
log_message "Process Manager started"
for process_name in "${MONITORED_PROCESSES[@]}"; do
init_process_monitor $process_name
monitor_process $process_name &
done
while true; do
if [ $(date +%H) -eq 0 ] && [ $(date +%M) -eq 0 ]; then
generate_monitor_report
fi
sleep 60
done
}
main智能进程分析系统#
#!/bin/bash
# 智能进程分析系统
ANALYSIS_DB="/var/lib/process_analysis/db"
LOG_FILE="/var/log/process_analysis/analysis.log"
mkdir -p $ANALYSIS_DB $(dirname $LOG_FILE)
# 收集进程信息
collect_process_info() {
local pid=$1
local output_dir="$ANALYSIS_DB/$pid"
mkdir -p $output_dir
# 基本信息
ps -p $pid -f > $output_dir/basic_info.txt
# 内存信息
ps -p $pid -o pid,vsz,rss,%mem,cmd > $output_dir/memory_info.txt
# CPU 信息
ps -p $pid -o pid,%cpu,etime,cmd > $output_dir/cpu_info.txt
# 文件描述符
ls -la /proc/$pid/fd/ > $output_dir/fd_info.txt 2>/dev/null
# 网络连接
netstat -p 2>/dev/null | grep $pid > $output_dir/network_info.txt
# 保存元数据
echo "pid=$pid" > $output_dir/metadata.txt
echo "timestamp=$(date)" >> $output_dir/metadata.txt
log_message "Process info collected for PID: $pid"
}
# 分析进程行为
analyze_process_behavior() {
local pid=$1
local output_dir="$ANALYSIS_DB/$pid"
if [ ! -d "$output_dir" ]; then
echo "Process info not found for PID: $pid"
return 1
fi
echo "=== Process Behavior Analysis ==="
echo "PID: $pid"
echo "Timestamp: $(grep timestamp $output_dir/metadata.txt | cut -d= -f2)"
echo ""
# CPU 使用分析
echo "CPU Usage:"
cat $output_dir/cpu_info.txt
echo ""
# 内存使用分析
echo "Memory Usage:"
cat $output_dir/memory_info.txt
echo ""
# 文件描述符分析
echo "File Descriptors:"
echo "Total: $(wc -l < $output_dir/fd_info.txt)"
echo ""
# 网络连接分析
echo "Network Connections:"
cat $output_dir/network_info.txt
}
# 检测异常进程
detect_anomalous_processes() {
echo "=== Anomalous Process Detection ==="
echo ""
# 高 CPU 使用
echo "High CPU Usage Processes (>50%):"
ps -eo pid,user,%cpu,cmd --sort=-%cpu | awk 'NR>1 && $3 > 50 {print $0}'
echo ""
# 高内存使用
echo "High Memory Usage Processes (>50%):"
ps -eo pid,user,%mem,cmd --sort=-%mem | awk 'NR>1 && $3 > 50 {print $0}'
echo ""
# 僵尸进程
echo "Zombie Processes:"
ps -eo stat,pid,cmd | grep "^Z"
echo ""
# 孤儿进程
echo "Orphan Processes:"
ps -eo pid,ppid,cmd | awk '$2 == 1 {print $0}'
}
# 进程性能基准测试
benchmark_process() {
local process_name=$1
local duration=$2
local output_file="benchmark_${process_name}_$(date +%Y%m%d_%H%M%S).txt"
echo "Benchmarking process: $process_name"
echo "Duration: $duration seconds"
echo ""
local iterations=$((duration / 5))
for ((i=1; i<=iterations; i++)); do
local pid=$(pgrep -o "$process_name")
if [ -n "$pid" ]; then
local cpu=$(ps -p $pid -o %cpu --no-headers)
local mem=$(ps -p $pid -o %mem --no-headers)
local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
echo "$timestamp - CPU: ${cpu}%, MEM: ${mem}%" >> $output_file
fi
sleep 5
done
echo "Benchmark completed: $output_file"
}
# 记录日志
log_message() {
local message=$1
local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
echo "[$timestamp] $message" >> $LOG_FILE
}
# 主函数
main() {
case "$1" in
collect)
collect_process_info "$2"
;;
analyze)
analyze_process_behavior "$2"
;;
detect)
detect_anomalous_processes
;;
benchmark)
benchmark_process "$2" "$3"
;;
*)
echo "Usage: $0 {collect|analyze|detect|benchmark}"
exit 1
;;
esac
}
main "$@"进程安全审计系统#
#!/bin/bash
# 进程安全审计系统
AUDIT_LOG="/var/log/process_audit/audit.log"
ALERT_LOG="/var/log/process_audit/alerts.log"
WHITELIST="/etc/process_audit/whitelist.conf"
mkdir -p $(dirname $AUDIT_LOG) $(dirname $ALERT_LOG)
# 审计进程权限
audit_process_permissions() {
echo "=== Process Permission Audit ===" >> $AUDIT_LOG
echo "Audit Time: $(date)" >> $AUDIT_LOG
echo "" >> $AUDIT_LOG
# root 用户运行的进程
echo "Root Processes:" >> $AUDIT_LOG
ps -eo pid,user,cmd | awk '$2 == "root" {print $0}' >> $AUDIT_LOG
echo "" >> $AUDIT_LOG
# SUID 进程
echo "SUID Processes:" >> $AUDIT_LOG
ps -eo pid,user,cmd | awk '{print $0}' | xargs -I {} readlink -f /proc/{}/exe 2>/dev/null | while read exe; do
if [ -n "$exe" ] && [ -u "$exe" ]; then
echo "$exe" >> $AUDIT_LOG
fi
done
echo "" >> $AUDIT_LOG
}
# 审计进程网络连接
audit_process_network() {
echo "=== Process Network Audit ===" >> $AUDIT_LOG
echo "Audit Time: $(date)" >> $AUDIT_LOG
echo "" >> $AUDIT_LOG
# 监听端口的进程
echo "Listening Processes:" >> $AUDIT_LOG
netstat -tlnp 2>/dev/null | grep LISTEN >> $AUDIT_LOG
echo "" >> $AUDIT_LOG
# 建立连接的进程
echo "Connected Processes:" >> $AUDIT_LOG
netstat -tnp 2>/dev/null | grep ESTABLISHED >> $AUDIT_LOG
echo "" >> $AUDIT_LOG
}
# 审计进程文件访问
audit_process_files() {
echo "=== Process File Access Audit ===" >> $AUDIT_LOG
echo "Audit Time: $(date)" >> $AUDIT_LOG
echo "" >> $AUDIT_LOG
# 打开敏感文件的进程
local sensitive_files=("/etc/passwd" "/etc/shadow" "/etc/hosts")
for file in "${sensitive_files[@]}"; do
echo "Processes accessing $file:" >> $AUDIT_LOG
lsof $file 2>/dev/null >> $AUDIT_LOG
echo "" >> $AUDIT_LOG
done
}
# 检测可疑进程
detect_suspicious_processes() {
echo "=== Suspicious Process Detection ===" >> $ALERT_LOG
echo "Detection Time: $(date)" >> $ALERT_LOG
echo "" >> $ALERT_LOG
# 检查未知进程
ps -eo pid,user,cmd | while read line; do
local pid=$(echo $line | awk '{print $1}')
local user=$(echo $line | awk '{print $2}')
local cmd=$(echo $line | awk '{print $3}')
# 检查是否在白名单中
if [ -f "$WHITELIST" ]; then
if ! grep -q "$cmd" $WHITELIST; then
echo "Unknown process: $line" >> $ALERT_LOG
fi
fi
done
echo "" >> $ALERT_LOG
# 检查隐藏进程
echo "Hidden Processes:" >> $ALERT_LOG
local ps_count=$(ps -e | wc -l)
local proc_count=$(ls /proc | grep -E '^[0-9]+$' | wc -l)
if [ $ps_count -lt $proc_count ]; then
echo "Possible hidden processes detected" >> $ALERT_LOG
echo "PS count: $ps_count, /proc count: $proc_count" >> $ALERT_LOG
fi
echo "" >> $ALERT_LOG
}
# 生成审计报告
generate_audit_report() {
local report_file="/var/log/process_audit/audit_report_$(date +%Y%m%d).txt"
echo "Process Security Audit Report - $(date +%Y-%m-%d)" > $report_file
echo "===================================" >> $report_file
echo "" >> $report_file
# 权限审计
echo "Permission Audit:" >> $report_file
grep "Root Processes:" $AUDIT_LOG -A 100 | head -20 >> $report_file
echo "" >> $report_file
# 网络审计
echo "Network Audit:" >> $report_file
grep "Listening Processes:" $AUDIT_LOG -A 100 | head -20 >> $report_file
echo "" >> $report_file
# 可疑进程
echo "Suspicious Processes:" >> $report_file
tail -50 $ALERT_LOG >> $report_file
echo "Audit report generated: $report_file"
}
# 主审计循环
main_audit() {
while true; do
audit_process_permissions
audit_process_network
audit_process_files
detect_suspicious_processes
# 每天生成一次报告
if [ $(date +%H) -eq 0 ] && [ $(date +%M) -eq 0 ]; then
generate_audit_report
fi
sleep $AUDIT_INTERVAL
done
}
# 主函数
main() {
case "$1" in
audit)
main_audit
;;
report)
generate_audit_report
;;
*)
echo "Usage: $0 {audit|report}"
exit 1
;;
esac
}
main "$@"最佳实践#
- 结合 grep 使用:使用
ps | grep筛选特定进程 - 使用 pgrep/pkill:对于简单的进程查找和终止,使用 pgrep/pkill
- 关注进程状态:注意进程的状态(R、S、Z、T 等)
- 监控资源使用:定期监控进程的 CPU 和内存使用
- 处理僵尸进程:及时发现和处理僵尸进程
- 理解进程关系:了解进程之间的父子关系
- 使用自定义输出:根据需要自定义输出字段
- 记录进程信息:定期记录进程信息,便于分析
注意事项#
- ps 只显示瞬间的进程状态,不是实时监控
- 不同版本的 ps 选项可能有所不同
- ps 的输出可能因系统而异
- 在高负载系统中,ps 的执行可能需要较长时间
- 注意僵尸进程的处理,避免资源泄漏
- 对于关键进程,建议使用专业的监控工具
- 在自动化脚本中使用 ps 时,注意错误处理
- 注意进程权限,某些进程信息可能无法查看
- 在生产环境中操作进程时要格外小心