本文目录导读:

我来详细说明Shell脚本配置邮件报警的几种常用方法。
安装邮件工具
Ubuntu/Debian系统
# 安装mailutils和sendmail sudo apt-get install mailutils sendmail sendmail-cf # 或者使用heirloom-mailx sudo apt-get install heirloom-mailx # 配置Postfix(如需发送外部邮件) sudo apt-get install postfix
CentOS/RHEL系统
# 安装mailx sudo yum install mailx # 安装sendmail sudo yum install sendmail sendmail-cf
配置邮件发送
使用本地Sendmail(最简单的配置)
# 启动sendmail服务 sudo systemctl start sendmail sudo systemctl enable sendmail
使用外部SMTP服务器(如QQ邮箱、163邮箱等)
创建配置文件 ~/.mailrc 或 /etc/mail.rc:
# QQ邮箱示例 set from=yourname@qq.com set smtp=smtp.qq.com set smtp-auth-user=yourname@qq.com set smtp-auth-password=your-auth-code # QQ邮箱使用授权码 set smtp-auth=login set ssl-verify=ignore
基础邮件报警脚本
简单的邮件发送函数
#!/bin/bash
# 邮件配置
TO_EMAIL="admin@example.com"
FROM_EMAIL="monitor@example.com"
SUBJECT_PREFIX="[服务器报警]"
# 发送邮件函数
send_email() {
local subject="$1"
local body="$2"
echo "$body" | mail -s "${SUBJECT_PREFIX}${subject}" "$TO_EMAIL"
}
# 使用示例
send_email "CPU使用率过高" "警告:CPU使用率已超过90%"
带附件的邮件发送
#!/bin/bash
send_email_with_attachment() {
local subject="$1"
local body="$2"
local attachment="$3"
# 使用mutt发送带附件的邮件
echo "$body" | mutt -s "${SUBJECT_PREFIX}${subject}" \
-a "$attachment" -- "$TO_EMAIL"
# 或者使用mailx
# echo "$body" | mailx -s "${SUBJECT_PREFIX}${subject}" \
# -A "$attachment" "$TO_EMAIL"
}
完整的监控报警脚本
#!/bin/bash
# ==================== 配置区域 ====================
ADMIN_EMAIL="admin@example.com"
HOSTNAME=$(hostname)
LOG_FILE="/var/log/monitor_alerts.log"
# 阈值配置
CPU_THRESHOLD=80
MEM_THRESHOLD=90
DISK_THRESHOLD=85
LOAD_THRESHOLD=5
# ==================== 函数定义 ====================
# 日志记录
log_message() {
local level="$1"
local message="$2"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$level] $message" >> "$LOG_FILE"
}
# 发送报警邮件
send_alert() {
local alert_type="$1"
local alert_value="$2"
local alert_message="$3"
# 构建邮件内容
local subject="[${HOSTNAME}] ${alert_type} 异常警报"
local body="
===== 服务器报警通知 =====
服务器:${HOSTNAME}
时间:$(date '+%Y-%m-%d %H:%M:%S')
报警类型:${alert_type}
当前值:${alert_value}
详细信息:
${alert_message}
===============================
"
# 发送邮件
echo "$body" | mail -s "$subject" "$ADMIN_EMAIL"
# 记录日志
log_message "ALERT" "$alert_type: $alert_value - $alert_message"
}
# 检查CPU使用率
check_cpu() {
local cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1)
if (( $(echo "$cpu_usage > $CPU_THRESHOLD" | bc -l) )); then
send_alert "CPU使用率" "${cpu_usage}%" \
"CPU使用率 ${cpu_usage}% 超过阈值 ${CPU_THRESHOLD}%"
return 1
fi
log_message "INFO" "CPU使用率正常: ${cpu_usage}%"
return 0
}
# 检查内存使用率
check_memory() {
local mem_usage=$(free | grep Mem | awk '{print $3/$2 * 100.0}')
if (( $(echo "$mem_usage > $MEM_THRESHOLD" | bc -l) )); then
send_alert "内存使用率" "${mem_usage}%" \
"内存使用率 ${mem_usage}% 超过阈值 ${MEM_THRESHOLD}%"
return 1
fi
log_message "INFO" "内存使用率正常: ${mem_usage}%"
return 0
}
# 检查磁盘使用率
check_disk() {
# 检查所有挂载点
df -h | grep -vE '^Filesystem' | awk '{print $5 " " $6}' | while read -r output; do
local usage=$(echo "$output" | awk '{print $1}' | cut -d'%' -f1)
local partition=$(echo "$output" | awk '{print $2}')
if [ "$usage" -ge "$DISK_THRESHOLD" ]; then
send_alert "磁盘使用率" "${usage}%" \
"分区 ${partition} 使用率 ${usage}% 超过阈值 ${DISK_THRESHOLD}%"
fi
done
}
# 检查系统负载
check_load() {
local load=$(uptime | awk -F'[a-z]:' '{print $2}' | awk '{print $1}' | tr -d ',')
if (( $(echo "$load > $LOAD_THRESHOLD" | bc -l) )); then
send_alert "系统负载" "${load}" \
"系统负载 ${load} 超过阈值 ${LOAD_THRESHOLD}"
return 1
fi
log_message "INFO" "系统负载正常: ${load}"
return 0
}
# 检查特定进程是否运行
check_process() {
local process_name="$1"
if ! pgrep -x "$process_name" > /dev/null; then
send_alert "进程异常" "${process_name}" \
"关键进程 ${process_name} 未运行,请立即检查!"
# 尝试重启进程
systemctl start "$process_name" 2>/dev/null || \
service "$process_name" start 2>/dev/null
log_message "WARN" "尝试重启进程: ${process_name}"
else
log_message "INFO" "进程运行正常: ${process_name}"
fi
}
# 检查网络连接
check_network() {
local target_host="$1"
if ping -c 3 -W 5 "$target_host" > /dev/null 2>&1; then
log_message "INFO" "网络连接正常: ${target_host}"
return 0
else
send_alert "网络异常" "${target_host}" \
"无法连接到 ${target_host},网络可能存在问题"
return 1
fi
}
# ==================== 主程序 ====================
main() {
echo "开始系统监控检查..."
log_message "INFO" "开始监控检查"
# 执行各项检查
check_cpu
check_memory
check_disk
check_load
# 检查关键进程
check_process "nginx"
check_process "mysql"
check_process "sshd"
# 检查网络连接
check_network "8.8.8.8"
check_network "www.baidu.com"
echo "监控检查完成"
log_message "INFO" "监控检查完成"
}
# 执行主程序
main
高级报警功能
带错误级别和告警抑制
#!/bin/bash
# 告警级别
ALERT_LEVELS=("INFO" "WARNING" "CRITICAL")
# 告警抑制(防止重复报警)
declare -A ALERT_CACHE
SUPPRESS_INTERVAL=300 # 5分钟内不重复告警
can_send_alert() {
local alert_key="$1"
local current_time=$(date +%s)
if [[ -n "${ALERT_CACHE[$alert_key]}" ]]; then
local last_time=${ALERT_CACHE[$alert_key]}
local time_diff=$((current_time - last_time))
if (( time_diff < SUPPRESS_INTERVAL )); then
return 1 # 在抑制时间内,不发送
fi
fi
# 更新时间
ALERT_CACHE[$alert_key]=$current_time
return 0 # 可以发送
}
# HTML格式邮件
send_html_email() {
local to="$1"
local subject="$2"
local html_content="$3"
# 使用mutt发送HTML邮件
echo "$html_content" | mutt -e "my_hdr Content-Type: text/html" \
-s "$subject" "$to"
}
定时执行(crontab配置)
# 编辑crontab crontab -e # 添加定时任务 # 每5分钟检查一次 */5 * * * * /path/to/monitor.sh # 每小时检查一次 0 * * * * /path/to/monitor.sh # 每天凌晨2点发送日报 0 2 * * * /path/to/daily_report.sh
使用第三方邮件服务
使用sendEmail工具(更简单)
# 安装sendEmail
sudo apt-get install sendemail
# 发送邮件示例
sendEmail -f sender@example.com \
-t receiver@example.com \
-u "邮件主题" \
-m "邮件内容" \
-s smtp.example.com:587 \
-o tls=yes \
-xu sender@example.com \
-xp "password"
使用curl发送(支持多种API)
#!/bin/bash
# SendGrid示例
send_sendgrid_email() {
local api_key="YOUR_SENDGRID_API_KEY"
local to_email="$1"
local subject="$2"
local content="$3"
curl --request POST \
--url https://api.sendgrid.com/v3/mail/send \
--header "Authorization: Bearer $api_key" \
--header "Content-Type: application/json" \
--data "{
\"personalizations\": [{\"to\": [{\"email\": \"$to_email\"}]}],
\"from\": {\"email\": \"monitor@yourdomain.com\"},
\"subject\": \"$subject\",
\"content\": [{\"type\": \"text/plain\", \"value\": \"$content\"}]
}"
}
注意事项
- 安全性:不要在脚本中硬编码密码,使用配置文件或环境变量
- 日志记录:记录所有报警动作,便于追踪
- 告警抑制:避免短时间内重复报警
- 测试验证:上线前充分测试邮件发送功能
- 备用方案:配置多个收件人,主备切换
这样配置后,你的Shell脚本就具备了完整的邮件报警功能了。