Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 125 additions & 0 deletions bin/memory-monitor
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
#!/bin/bash
# ==============================================================================
# 内存监控脚本(Memory Monitor)
# 功能:列出系统内存占用TOP N的进程,支持自定义数量,VSZ/RSS以MB显示,输出规范化
# 作者:[email protected] | https://github.com/huchuansai
# 用法:
# ./memory-monitor.sh # 默认显示TOP 15高内存进程
# ./memory-monitor.sh 20 # 显示TOP 20高内存进程
# ./memory-monitor.sh -h/--help # 查看帮助
# 兼容:CentOS/Ubuntu/Debian等主流Linux发行版
# ==============================================================================

set -o nounset # 未定义变量时退出,避免语法错误
set -o pipefail # 管道中任一命令失败则整体失败

# ========================== 配置常量(可自定义)==========================
DEFAULT_TOP_N=15 # 默认显示TOP 15进程
COLOR_ENABLE=true # 是否启用彩色输出(true/false)
SEPARATOR="=====================================================================================================" # 适配列宽的分隔线
# 彩色编码(按需调整)
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # 重置颜色

# ========================== 核心函数 ===========================
# 1. 帮助信息函数
show_help() {
echo -e "\n${BLUE}=== 内存监控脚本(Memory Monitor)===${NC}"
echo "用途:列出系统中内存占用最高的进程,支持自定义显示数量,VSZ/RSS以MB显示"
echo "用法:"
echo " $0 [OPTIONS] [N]"
echo "参数说明:"
echo " N 可选,要显示的进程数量(正整数),默认${DEFAULT_TOP_N}"
echo " -h/--help 显示帮助信息并退出"
echo "示例:"
echo " $0 # 显示TOP ${DEFAULT_TOP_N}高内存进程"
echo " $0 20 # 显示TOP 20高内存进程"
echo -e "${YELLOW}注意:需在Linux系统运行,root用户可查看所有进程,普通用户仅能查看自身进程${NC}\n"
}

# 2. 参数校验函数
validate_param() {
local input=$1
# 检查是否为正整数
if ! [[ "$input" =~ ^[1-9][0-9]*$ ]]; then
echo -e "${RED}错误:参数必须是正整数(如 10、20)!${NC}" >&2
show_help
exit 1
fi
}

# 3. 核心监控函数(VSZ/RSS转MB+列对齐+时间标准化)
memory_monitor() {
local top_n=$1

# 一次性获取ps数据(lstart为完整启动时间,-ww确保CMD不截断,按内存降序)
# 列顺序:user,pid,%cpu,%mem,vsz,rss,lstart,time,cmd
local ps_data
ps_data=$(ps -eo user,pid,%cpu,%mem,vsz,rss,lstart,time,cmd --sort=-%mem -ww)

# 输出头部信息
echo -e "\n${SEPARATOR}"
echo -e "${GREEN}【内存监控报告】${NC}"
echo -e "主机名:$(hostname)"
echo -e "执行时间:$(date +'%Y-%m-%d %H:%M:%S')"
echo -e "显示进程数:TOP ${top_n}"
echo -e "${SEPARATOR}"

# 输出列说明(VSZ/RSS改为MB,精准对齐列宽)
echo -e "${YELLOW}列说明:${NC}USER(用户) | PID(进程ID) | %CPU(CPU占用率) | %MEM(内存占用率) | VSZ(虚拟内存MB) | RSS(物理内存MB) | START(启动时间) | TIME(CPU累计时间) | CMD(完整命令)"
echo -e "${SEPARATOR}"

# 处理表头(格式化)
echo "$ps_data" | head -1 | awk '{
# 表头列宽:USER(8) PID(8) %CPU(8) %MEM(8) VSZ(12) RSS(12) START(20) TIME(12) CMD(剩余)
printf "%-8s %-8s %-8s %-8s %-12s %-12s %-20s %-12s %s\n",
$1, $2, $3, $4, "VSZ(MB)", "RSS(MB)", "START", "TIME", $10
}'

# 处理数据行(核心:VSZ/RSS转MB+时间标准化+列对齐)
echo "$ps_data" | tail -n +2 | head -"$top_n" | awk '{
# 1. VSZ(KB)转MB,保留1位小数($5=VSZ原始值)
vsz_mb = sprintf("%.1f", $5/1024);
# 2. RSS(KB)转MB,保留1位小数($6=RSS原始值)
rss_mb = sprintf("%.1f", $6/1024);

# 3. 拼接lstart完整时间字符串并转换为YYYY-MM-DD HH:MM:SS
lstart_str = $7 " " $8 " " $9 " " $10 " " $11;
fmt_start = "";
cmd = sprintf("date -d \"%s\" +\"%%Y-%%m-%%d %%H:%%M:%%S\"", lstart_str);
if ((cmd | getline fmt_start) <= 0) {
fmt_start = lstart_str;
}
close(cmd);

# 4. 拼接完整CMD(从$13开始到最后)
cmd_str = "";
for(i=13; i<=NF; i++) {
cmd_str = cmd_str $i " ";
}

# 5. 严格对齐列宽输出
printf "%-8s %-8s %-8s %-8s %-12s %-12s %-20s %-12s %s\n",
$1, $2, $3, $4, vsz_mb, rss_mb, fmt_start, $12, cmd_str;
}'

# 输出尾部信息
echo -e "${SEPARATOR}"
echo -e "${GREEN}监控完成 ✔️${NC}\n"
}

# ========================== 主逻辑 ===========================
if [[ $# -eq 0 ]]; then
memory_monitor "$DEFAULT_TOP_N"
elif [[ $1 == "-h" || $1 == "--help" ]]; then
show_help
exit 0
else
validate_param "$1"
memory_monitor "$1"
fi

exit 0
5 changes: 5 additions & 0 deletions bin/memory-monitor-simple
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash

set -e # Exit the script if an error happens
#set -x
ps auxw|head -1;ps auxw|sort -rn -k4|head -20