脚本作业解析
这是一个使用 msmtp
命令行邮件客户端发送邮件的 Bash 函数。让我为您详细解析这个函数:
发送邮件函数
函数结构
send_alert_email() {local subject="$1" # 第一个参数:邮件主题local content="$2" # 第二个参数:邮件内容
邮件发送流程
-
构造邮件内容:
echo -e "Subject: $subject\n\n$message" | \
使用
echo -e
生成包含主题和内容的邮件正文,通过管道传递给msmtp
-
配置 SMTP 参数:
SMTP_PASSWORD="$SMTP_PASS" msmtp \--from="$SMTP_USER" \ # 发件人地址--host="$SMTP_SERVER" \ # SMTP 服务器地址--port="$SMTP_PORT" \ # SMTP 端口号--auth=on \ # 启用认证--user="$SMTP_USER" \ # 登录用户名--passwordeval="echo \$SMTP_PASSWORD" \ # 密码获取方式--tls=on \ # 启用 TLS--tls-starttls=on \ # 使用 STARTTLS"$EMAIL" # 收件人地址
-
检查发送结果:
if [ $? -eq 0 ]; thenecho "邮件发送成功: $subject" elseecho "邮件发送失败: $subject" fi
存在的问题
-
变量名不一致:
- 函数参数
$content
但实际使用的是$message
- 应该改为:
echo -e "Subject: $subject\n\n$content"
- 函数参数
-
环境变量依赖:
SMTP_PASS
,SMTP_USER
,SMTP_SERVER
,SMTP_PORT
,EMAIL
都需要提前设置
使用方法
# 设置环境变量
export SMTP_USER="your-email@example.com"
export SMTP_PASS="your-password"
export SMTP_SERVER="smtp.example.com"
export SMTP_PORT="587"
export EMAIL="recipient@example.com"# 发送邮件
send_alert_email "测试主题" "这是邮件内容"
这个函数提供了基本的邮件告警功能,适合在脚本中用于发送通知和警报。
检查CPU使用率
这是一个检查 CPU 使用率的 Bash 函数。让我为您详细解析:
函数结构
check_cpu() {local cpu_usage_int=$(printf "%.0f" "$cpu_usage") # 将浮点数转换为整数if [ "$cpu_usage_int" -gt "$THRESHOLD" ]; thensend_alert_email "CPU" "$cpu_usage_int" "CPU使用率过高,请及时处理"return 1 # 返回非零表示异常elselog_message "CPU使用率正常: ${cpu_usage_int}%"return 0 # 返回零表示正常fi
}
关键组件解析
-
数值转换:
local cpu_usage_int=$(printf "%.0f" "$cpu_usage")
- 使用
printf "%.0f"
将浮点数 CPU 使用率四舍五入为整数 - 例如:
12.6%
→13
,12.4%
→12
- 使用
-
阈值比较:
if [ "$cpu_usage_int" -gt "$THRESHOLD" ]; then
- 比较当前 CPU 使用率是否超过预设阈值
$THRESHOLD
-gt
表示大于比较
- 比较当前 CPU 使用率是否超过预设阈值
-
告警机制:
send_alert_email "CPU" "$cpu_usage_int" "CPU使用率过高,请及时处理"
- 调用之前定义的邮件发送函数
- 参数:监控对象、当前值、告警信息
-
日志记录:
log_message "CPU使用率正常: ${cpu_usage_int}%"
- 正常状态下记录日志(假设
log_message
函数已定义)
- 正常状态下记录日志(假设
依赖的全局变量
$cpu_usage
:CPU 使用率百分比(浮点数)$THRESHOLD
:告警阈值(整数)
使用示例
# 设置阈值
THRESHOLD=80# 获取 CPU 使用率(示例)
cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1)# 调用检查函数
if check_cpu; thenecho "CPU 状态正常"
elseecho "CPU 使用率过高"
fi
这个函数是监控系统中典型的阈值检查模式,适用于各种资源监控场景。
检查内存使用率
这是一个检查内存使用率的 Bash 函数。让我为您详细解析:
函数结构
check_memory() {# 获取内存信息local mem_info=$(free | grep Mem)local total_mem=$(echo $mem_info | awk '{print $2}')local used_mem=$(echo $mem_info | awk '{print $3}')# 计算使用率local mem_usage=$(awk "BEGIN {printf \"%.2f\", $used_mem/$total_mem*100}")local mem_usage_int=$(printf "%.0f" "$mem_usage")# 阈值检查if [ "$mem_usage_int" -gt "$THRESHOLD" ]; thensend_alert_email "内存" "$mem_usage_int" "内存使用率过高,可能需要释放内存或增加内存"return 1elselog_message "内存使用率正常: ${mem_usage_int}%"return 0fi
}
关键组件解析
-
获取内存信息:
local mem_info=$(free | grep Mem)
- 使用
free
命令获取内存信息 grep Mem
过滤出内存相关的行
- 使用
-
提取具体数值:
local total_mem=$(echo $mem_info | awk '{print $2}') # 总内存(KB) local used_mem=$(echo $mem_info | awk '{print $3}') # 已用内存(KB)
-
计算使用率:
local mem_usage=$(awk "BEGIN {printf \"%.2f\", $used_mem/$total_mem*100}")
- 计算百分比:已用内存 / 总内存 × 100
- 保留两位小数
-
转换为整数:
local mem_usage_int=$(printf "%.0f" "$mem_usage")
- 四舍五入为整数,便于阈值比较
技术细节说明
- 单位:
free
命令默认输出以 KB 为单位 - 内存计算:使用的是
used_mem
(已用内存),不包括缓存和缓冲区 - 精度处理:先计算浮点数,再转换为整数进行比较
依赖的全局变量
$THRESHOLD
:告警阈值(整数百分比)
使用示例
# 设置阈值
THRESHOLD=80# 调用检查函数
if check_memory; thenecho "内存状态正常"
elseecho "内存使用率过高"
fi
输出示例
假设内存情况:
- 总内存:8,192,000 KB (8GB)
- 已用内存:6,553,600 KB (6.4GB)
计算过程:
mem_usage = 6553600 / 8192000 * 100 = 80.00%
mem_usage_int = 80
这个函数提供了基本的内存监控功能,适合在服务器监控脚本中使用。
检查磁盘使用率
这是一个检查磁盘使用率的 Bash 函数。让我为您详细解析:
函数结构
check_disk() {# 获取根分区磁盘使用率local disk_usage=$(df -h / | grep / | awk '{print $5}' | sed 's/%//g')# 阈值检查if [ $disk_usage -ge $THRESHOLD ]; thenlocal subject="磁盘使用率告警"local message="根目录磁盘使用率过高: $disk_usage%,超过阈值$THRESHOLD%。\n时间: $(date)"send_alert "$subject" "$message"echo "磁盘告警已发送: $disk_usage%"fi
}
关键组件解析
-
获取磁盘使用率:
local disk_usage=$(df -h / | grep / | awk '{print $5}' | sed 's/%//g')
df -h /
:查看根分区的磁盘使用情况,-h
表示人类可读格式grep /
:过滤出包含"/"的行(根分区)awk '{print $5}'
:提取第5列(使用率百分比)sed 's/%//g'
:移除百分号,只保留数字
-
阈值比较:
if [ $disk_usage -ge $THRESHOLD ]; then
-ge
表示大于或等于比较
-
构造告警信息:
local subject="磁盘使用率告警" local message="根目录磁盘使用率过高: $disk_usage%,超过阈值$THRESHOLD%。\n时间: $(date)"
-
发送告警:
send_alert "$subject" "$message"
- 调用
send_alert
函数(注意:之前使用的是send_alert_email
)
- 调用
技术细节说明
- 监控目标:只监控根分区
/
- 输出格式:
df -h
显示人类可读格式(G、M、K) - 返回值:函数没有明确的 return 语句,依赖外部判断
依赖的全局变量
$THRESHOLD
:告警阈值(整数百分比)
使用示例
# 设置阈值
THRESHOLD=85# 调用检查函数
check_disk
输出示例
假设磁盘情况:
文件系统 容量 已用 可用 已用% 挂载点
/dev/sda1 50G 45G 2.0G 96% /
提取过程:
df -h / → 输出上述信息
grep / → 过滤出包含"/"的行
awk '{print $5}' → 提取"96%"
sed 's/%//g' → 得到"96"
检查IO await
这是一个检查 IO await 时间的 Bash 函数。让我为您详细解析:
函数结构
check_io_await() {# 获取IO await值local io_await=$(iostat -x 1 2 | awk '/^avg-cpu/ {getline; getline; print $10}' | tail -n1)local io_await_int=$(printf "%.0f" "$io_await")# 阈值检查if [ "$io_await_int" -ge "$IO_AWAIT_THRESHOLD" ]; thenlocal message="IO await过高: ${io_await_int}ms (阈值: ${IO_AWAIT_THRESHOLD}ms)"log_message "警告: $message"send_alert_email "IO await告警 - $TIMESTAMP" "$message\n服务器: $(hostname)"fi
}
关键组件解析
1. 获取 IO await 值
local io_await=$(iostat -x 1 2 | awk '/^avg-cpu/ {getline; getline; print $10}' | tail -n1)
分解说明:
-
iostat -x 1 2
:显示扩展磁盘统计信息-x
:显示扩展统计信息1 2
:每秒采样一次,共采样2次
-
awk '/^avg-cpu/ {getline; getline; print $10}'
:/^avg-cpu/
:匹配以"avg-cpu"开头的行(CPU统计标题行)getline
:读取下一行(设备列表标题行)getline
:再读取下一行(第一个设备的数据行)print $10
:打印第10列(await值)
-
tail -n1
:取最后一行(避免第一次采样的冷启动数据)
2. 数值处理
local io_await_int=$(printf "%.0f" "$io_await")
- 将浮点数 await 值四舍五入为整数
3. 阈值检查
if [ "$io_await_int" -ge "$IO_AWAIT_THRESHOLD" ]; then
-ge
:大于或等于比较
什么是 IO await?
IO await 是重要的磁盘性能指标:
- 定义:平均每次I/O操作的等待时间(毫秒)
- 含义:从发出I/O请求到完成的时间
- 正常范围:
- < 10ms:优秀
- 10-20ms:良好
- 20-50ms:一般
-
50ms:可能存在性能问题
依赖的全局变量
$IO_AWAIT_THRESHOLD
:IO await 告警阈值(毫秒)$TIMESTAMP
:时间戳(用于邮件主题)$(hostname)
:服务器主机名
使用示例
# 设置阈值(单位:毫秒)
IO_AWAIT_THRESHOLD=50
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')# 调用检查函数
check_io_await
输出示例
假设 iostat -x 1 2
输出:
avg-cpu: %user %nice %system %iowait %steal %idle1.50 0.00 0.50 5.25 0.00 92.75Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
sda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sdb 0.00 5.00 10.00 20.00 400.00 800.00 80.00 1.50 50.00 40.00 55.00 3.00 15.00
提取过程:
- 匹配
avg-cpu
行 - 跳过下一行(设备标题)
- 读取再下一行(sda设备),取第10列:
0.00
- 读取最后一行(sdb设备),取第10列:
50.00
tail -n1
取最后的值:50.00
常见问题排查
当 IO await 过高时,可能的原因:
- 磁盘过载:I/O请求太多
- 硬件问题:磁盘故障或性能下降
- 配置问题:RAID配置不当
- 应用问题:大量小文件读写
这个函数是磁盘性能监控的重要组成部分,帮助及时发现存储瓶颈。
检查网络流量
这是一个检查网络流量的 Bash 函数。让我为您详细解析:
函数结构
check_network() {# 获取网络接口和初始字节计数local interface=$(ip route | grep default | awk '{print $5}' | head -n1)local rx_bytes_prev=$(cat /sys/class/net/$interface/statistics/rx_bytes 2>/dev/null)local tx_bytes_prev=$(cat /sys/class/net/$interface/statistics/tx_bytes 2>/dev/null)# 等待1秒采集数据sleep 1# 获取1秒后的字节计数local rx_bytes_next=$(cat /sys/class/net/$interface/statistics/rx_bytes 2>/dev/null)local tx_bytes_next=$(cat /sys/class/net/$interface/statistics/tx_bytes 2>/dev/null)# 计算网络速度local rx_speed=$(echo "scale=2; ($rx_bytes_next - $rx_bytes_prev) / 1024 / 1024" | bc)local tx_speed=$(echo "scale=2; ($tx_bytes_next - $tx_bytes_prev) / 1024 / 1024" | bc)# 检查下载速度if [ $(echo "$rx_speed > $NETWORK_THRESHOLD" | bc) -eq 1 ]; thenlocal message="网络下载流量过高: ${rx_speed}MB/s (阈值: ${NETWORK_THRESHOLD}MB/s)"log_message "警告: $message"send_alert_email "网络流量告警 - $TIMESTAMP" "$message\n接口: $interface\n服务器: $(hostname)"fi# 检查上传速度if [ $(echo "$tx_speed > $NETWORK_THRESHOLD" | bc) -eq 1 ]; thenlocal message="网络上载流量过高: ${tx_speed}MB/s (阈值: ${NETWORK_THRESHOLD}MB/s)"log_message "警告: $message"send_alert_email "网络流量告警 - $TIMESTAMP" "$message\n接口: $interface\n服务器: $(hostname)"fi
}
关键组件解析
1. 获取默认网络接口
local interface=$(ip route | grep default | awk '{print $5}' | head -n1)
ip route
:显示路由表grep default
:过滤出默认路由awk '{print $5}'
:提取第5列(接口名称)head -n1
:取第一个默认路由接口
2. 读取网络统计信息
local rx_bytes_prev=$(cat /sys/class/net/$interface/statistics/rx_bytes 2>/dev/null)
local tx_bytes_prev=$(cat /sys/class/net/$interface/statistics/tx_bytes 2>/dev/null)
rx_bytes
:接收字节数(下载)tx_bytes
:发送字节数(上传)2>/dev/null
:忽略错误输出
3. 计算网络速度
local rx_speed=$(echo "scale=2; ($rx_bytes_next - $rx_bytes_prev) / 1024 / 1024" | bc)
- 计算公式:
(当前字节数 - 1秒前字节数) / 1024 / 1024
- 单位转换:字节 → KB → MB
scale=2
:保留2位小数bc
:用于浮点数计算
4. 阈值比较
if [ $(echo "$rx_speed > $NETWORK_THRESHOLD" | bc) -eq 1 ]; then
- 使用
bc
进行浮点数比较 -eq 1
:bc 返回1表示条件为真
技术细节说明
文件位置说明
/sys/class/net/eth0/statistics/rx_bytes
:接收字节数/sys/class/net/eth0/statistics/tx_bytes
:发送字节数
单位换算
- 1 MB = 1024 KB = 1024 × 1024 字节
- 速度计算:Δ字节数 / 时间间隔
依赖的全局变量
$NETWORK_THRESHOLD
:网络流量阈值(MB/s)$TIMESTAMP
:时间戳$(hostname)
:服务器主机名
使用示例
# 设置阈值(MB/s)
NETWORK_THRESHOLD=10
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')# 调用检查函数
check_network
计算示例
假设:
- 初始接收字节:100,000,000
- 1秒后接收字节:110,000,000
- 计算:
rx_speed = (110,000,000 - 100,000,000) / 1024 / 1024= 10,000,000 / 1,048,576= 9.54 MB/s
这个函数是网络性能监控的重要组件,帮助及时发现网络带宽瓶颈或异常流量。