Shell 脚本 / 命令文档
Shell编程实战教程
概述
系统资源实时监控脚本开发
编写思路 注意事项 完整成品
1.1 需求分析
系统资源监控脚本需要实时监控以下关键指标:
CPU使用率 - 判断系统计算负载
内存使用情况 - 监控内存占用和可用空间
磁盘使用率 - 防止磁盘空间耗尽
网络流量 - 监控网络IO状态
系统负载 - Load Average指标
1.2 程序流程图
初始化配置
检查依赖命令
循环监控
采集系统数据
格式化输出
阈值告警判断
等待刷新间隔
1.3 核心技术点
CPU监控
# 方法1:使用top命令
cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1)
# 方法2:使用mpstat(需要sysstat包)
cpu_usage=$(mpstat 1 1 | awk '/Average/ {print 100-$NF}')
# 方法3:读取/proc/stat
grep 'cpu ' /proc/stat内存监控
# 使用free命令
mem_total=$(free -m | awk '/Mem:/ {print $2}')
mem_used=$(free -m | awk '/Mem:/ {print $3}')
mem_percent=$(awk "BEGIN {printf \"%.1f\", ($mem_used/$mem_total)*100}")磁盘监控
# 使用df命令
disk_usage=$(df -h / | awk 'NR==2 {print $5}' | sed 's/%//')
disk_total=$(df -h / | awk 'NR==2 {print $2}')
disk_used=$(df -h / | awk 'NR==2 {print $3}')网络监控
# 读取网络接口统计信息 rx_before=$(cat /sys/class/net/eth0/statistics/rx_bytes) tx_before=$(cat /sys/class/net/eth0/statistics/tx_bytes) sleep 1 rx_after=$(cat /sys/class/net/eth0/statistics/rx_bytes) tx_after=$(cat /sys/class/net/eth0/statistics/tx_bytes)
1.4 数据处理流程
数据采集:从系统命令和/proc文件系统读取原始数据
数据解析:使用awk、sed、grep等工具提取关键信息
数据计算:进行百分比、平均值等计算
数据格式化:使用printf进行格式化输出
阈值判断:与预设阈值比较,触发告警
关键注意点
脚本必须有执行权限:chmod +x monitor.sh
某些命令需要root权限或sudo
确保依赖命令已安装(top, free, df, awk等)
长时间运行要考虑资源占用
2.1 兼容性问题
不同Linux发行版的差异: 命令输出格式:CentOS、Ubuntu、Debian的top/free输出格式可能不同 网络接口名称:eth0、ens33、enp0s3等命名规则不同 工具包名称:如sysstat在不同系统中的包名可能不同
# 检测网络接口的通用方法
INTERFACE=$(ip route | grep default | awk '{print $5}' | head -1)
# 或者使用:
INTERFACE=$(ls /sys/class/net | grep -v lo | head -1)2.2 性能优化
优化建议: 减少命令调用:将多次调用合并为一次 避免频繁读取文件:合理设置刷新间隔 使用内建命令:优先使用Shell内建命令而非外部命令 变量缓存:对不变的数据进行缓存
# 不推荐:多次调用
mem_total=$(free -m | awk '/Mem:/ {print $2}')
mem_used=$(free -m | awk '/Mem:/ {print $3}')
# 推荐:一次调用获取多个值
read mem_total mem_used mem_free <<< $(free -m | awk '/Mem:/ {print $2,$3,$4}')2.3 错误处理
# 检查命令是否存在
if ! command -v top &> /dev/null; then
echo "错误: top命令未找到"
exit 1
fi
# 检查文件是否存在
if [ ! -f /proc/stat ]; then
echo "错误: /proc/stat文件不存在"
exit 1
fi
# 捕获除零错误
if [ $total -eq 0 ]; then
percent=0
else
percent=$((used*100/total))
fi2.4 日志记录
日志最佳实践: 使用时间戳标记每条日志 日志文件要定期轮转(logrotate) 区分不同级别:INFO、WARNING、ERROR 日志目录要有写权限
# 日志函数示例
LOG_FILE="/var/log/monitor.log"
log_message() {
local level=$1
shift
local message=$@
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$level] $message" >> $LOG_FILE
}2.5 安全考虑
避免在脚本中硬编码密码
日志文件权限设置为600或644
对用户输入进行验证和过滤
使用绝对路径调用命令,防止PATH劫持
定期检查脚本权限,防止被篡改
三、完整成品脚本
功能特性: 实时监控CPU、内存、磁盘、网络 彩色终端输出,美观易读 阈值告警功能 日志记录 优雅的信号处理 自动检测网络接口
(示例代码较长,完整实现见源文件 linux_monitor_tutorial.html)