
做 Linux 运维的小伙伴都清楚:服务器日常巡检是刚需工作,但手动巡检效率极低、极易漏项。
常规手动巡检需要逐一查看:系统版本、运行时长、CPU 负载、内存占用、磁盘使用率、磁盘 IO、监听端口、异常登录、服务运行状态等。一台服务器至少需要 5-10 分钟,甚至更长时间,服务器数量多了,不仅耗时费力,还容易因为人为疏忽遗漏潜在风险,导致小问题拖成线上故障。
今天给大家分享一套轻量级自动化巡检脚本,无需复杂操作,执行一条命令即可自动采集服务器全量状态,生成规整的 Markdown 格式巡检报告,同时支持自动邮件推送,搭配定时任务可实现每周全自动巡检,显著降低日常巡检的人工成本,规范化运维巡检工作。
相比于人工巡检,自动化脚本巡检具备无可替代的优势,完全适配中小企业、个人运维、服务器集群场景:
本脚本经过生产环境打磨,覆盖常见 Linux 服务器基础巡检需求,核心检测项如下:
该脚本输出标准 Markdown 报告,自带风险预警,支持邮件推送,代码规范、可直接线上部署。
新建脚本文件 server_inspect.sh:
#!/bin/bash
# ==============================================
# Linux 服务器轻量级自动化巡检脚本
# 功能:全量采集系统状态、生成Markdown报告、支持邮件推送
# 适配:CentOS / Ubuntu / Rocky Linux 主流发行版
# 作者:运维技术博客
# 更新:2026生产稳定版
# ==============================================
# ==================== 可自定义配置项 ====================
# 报告保存路径
REPORT_PATH="/var/log/server_inspect_report"
# 邮件接收地址(如需推送,自行修改)
MAIL_TO="admin@example.com"
# 磁盘使用率告警阈值(超过则标记风险)
DISK_WARN_THRESHOLD=85
# 内存使用率告警阈值
MEM_WARN_THRESHOLD=85
# ==========================================================
# 前置依赖检查
check_dependency() {
local missing=()
for cmd in bc sysstat ip; do
if ! command -v "$cmd" >/dev/null 2>&1; then
missing+=("$cmd")
fi
done
if [ ${#missing[@]} -gt 0 ]; then
echo"⚠️ 缺少依赖工具:${missing[*]}"
echo"请执行以下命令安装:"
echo"CentOS/Rocky Linux: yum install -y ${missing[*]}"
echo"Ubuntu: apt install -y ${missing[*]}"
exit 1
fi
}
check_dependency
# 获取当前时间
DATE=$(date +"%Y-%m-%d %H:%M:%S")
REPORT_FILE="${REPORT_PATH}/inspect_$(date +%Y%m%d_%H%M%S).md"
# 创建报告目录
mkdir -p "$REPORT_PATH"
# ==================== 生成Markdown巡检报告 ====================
cat > "$REPORT_FILE" << EOF
# 服务器自动化巡检报告
**巡检时间**:${DATE}
**服务器主机名**:$(hostname)
**服务器IP**:$(ip route get 1.1.1.1 2>/dev/null | awk '{print $7; exit}' || hostname -I 2>/dev/null | awk '{print $1}')
---
## 一、系统基础信息
EOF
# 系统版本信息
OS_VERSION=$(grep '^PRETTY_NAME=' /etc/os-release | cut -d= -f2 | tr -d '"')
KERNEL_VERSION=$(uname -r)
UPTIME=$(uptime -p)
cat >> "$REPORT_FILE" << EOF
- 系统版本:${OS_VERSION}
- 内核版本:${KERNEL_VERSION}
- 服务器运行时长:${UPTIME}
---
## 二、CPU 运行状态
EOF
# CPU信息
CPU_CORE=$(nproc)
read LOAD1 LOAD5 LOAD15 _ < /proc/loadavg
cat >> "$REPORT_FILE" << EOF
- CPU逻辑核心数:${CPU_CORE} 核
- 1分钟平均负载:${LOAD1}
- 5分钟平均负载:${LOAD5}
- 15分钟平均负载:${LOAD15}
EOF
# CPU负载风险判断(无需bc依赖)
if awk "BEGIN {exit !(${LOAD5} > ${CPU_CORE})}"; then
echo"- ⚠️ 【风险预警】CPU负载过高,存在性能瓶颈" >> "$REPORT_FILE"
fi
cat >> "$REPORT_FILE" << EOF
---
## 三、内存 & Swap 状态
EOF
# 内存信息(使用available计算真实可用内存,排除缓存影响)
MEM_TOTAL=$(free -h | awk '/Mem/ {print $2}')
MEM_USED=$(free -h | awk '/Mem/ {print $3}')
MEM_AVAILABLE=$(free -h | awk '/Mem/ {print $7}')
MEM_CACHE=$(free -h | awk '/Mem/ {print $6}')
SWAP_USED=$(free -h | awk '/Swap/ {print $3}')
cat >> "$REPORT_FILE" << EOF
- 总内存:${MEM_TOTAL}
- 已用内存:${MEM_USED}
- 可用内存:${MEM_AVAILABLE}
- 缓存占用:${MEM_CACHE}
- Swap已用:${SWAP_USED}
EOF
# 内存风险判断(基于available计算真实使用率)
MEM_USED_RATE=$(free | awk '/Mem/ {printf "%.0f", ($2-$7)/$2*100}')
if [ "$MEM_USED_RATE" -gt "$MEM_WARN_THRESHOLD" ]; then
echo"- ⚠️ 【风险预警】真实内存使用率超过${MEM_WARN_THRESHOLD}%,内存资源紧张" >> "$REPORT_FILE"
fi
cat >> "$REPORT_FILE" << EOF
> 💡 说明:Linux 会将空闲内存用于文件缓存提升性能,`可用内存` 更能真实反映系统内存状态。
---
## 四、磁盘空间使用状态
EOF
# 磁盘信息遍历(使用-hP保证格式稳定,跳过表头,保留overlay挂载)
df -hP | awk -v threshold="$DISK_WARN_THRESHOLD"'
BEGIN{print "| 文件系统 | 挂载目录 | 总容量 | 已用 | 剩余 | 使用率 | 状态 |\n|----------|----------|--------|-------|-------|--------|------|"}
NR>1 && $1 !~ /tmpfs|loop/ {
usage=$5
gsub(/%/,"",usage)
if(usage >= threshold){
status="⚠️ 风险"
}else{
status="✅ 正常"
}
printf "| %s | %s | %s | %s | %s | %s | %s |\n",$1,$6,$2,$3,$4,$5,status
}' >> "$REPORT_FILE"
cat >> "$REPORT_FILE" << EOF
---
## 五、磁盘IO 运行状态
EOF
# 磁盘IO检测(动态获取%util列,兼容不同sysstat版本)
ifcommand -v iostat >/dev/null 2>&1; then
IO_STATUS=$(iostat -dx 1 1 | awk '
/Device/ {
for(i=1;i<=NF;i++){
if($i=="%util") col=i
}
next
}
NR>3 {
printf "磁盘设备:%s 繁忙率:%.1f%%\n", $1, $col
}')
else
IO_STATUS="未安装iostat工具,无法检测IO状态(可执行 yum install sysstat 安装)"
fi
echo"${IO_STATUS}" >> "$REPORT_FILE"
cat >> "$REPORT_FILE" << EOF
---
## 六、网络监听端口列表
EOF
# 监听端口检测
ss -tuln | grep -v "UNCONN" | awk '{print $1,$5}' | sort | uniq >> "$REPORT_FILE"
cat >> "$REPORT_FILE" << EOF
---
## 七、近期系统登录记录(近10条)
EOF
# 登录日志
last | head -n 10 >> "$REPORT_FILE"
cat >> "$REPORT_FILE" << EOF
---
## 八、巡检总结
EOF
echo"- 巡检完成时间:${DATE}" >> "$REPORT_FILE"
echo"- 报告存储路径:${REPORT_FILE}" >> "$REPORT_FILE"
echo"- Markdown 报告建议使用 VSCode、Typora、Obsidian 等工具查看" >> "$REPORT_FILE"
# ==================== 邮件发送模块 ====================
send_mail() {
ifcommand -v mailx >/dev/null 2>&1; then
mailx -s "【服务器自动巡检报告】$(hostname)${DATE}""${MAIL_TO}" < "$REPORT_FILE"
fi
}
# 如需自动发邮件,取消下方注释
# send_mail
echo"✅ 服务器巡检完成!报告已生成:${REPORT_FILE}"
将脚本上传至服务器后,执行以下命令授权,确保脚本可正常运行:
chmod +x /root/server_inspect.sh
# 执行一键巡检
/root/server_inspect.sh
脚本执行完成后,会在 /var/log/server_inspect_report 目录生成独立的 Markdown 报告文件,文件名带时间戳,方便存档溯源:
# 查看所有巡检报告
ls /var/log/server_inspect_report/
# 查看最新报告内容
cat $(ls -lt /var/log/server_inspect_report/*.md | head -1 | awk '{print $9}')
脚本内置邮件推送功能,只需简单配置,即可实现巡检报告自动发送至运维邮箱,无需登录服务器查看。
# CentOS / Rocky Linux
yum install -y mailx postfix
# Ubuntu
apt install -y mailutils postfix
修改脚本内 可自定义配置项 中的邮箱地址,然后取消脚本末尾 send_mail 注释,即可开启自动推送。
💡 运维提示:若需发送外网邮箱(QQ / 企业邮箱),需额外配置 Postfix SMTP 中继,否则仅支持本地邮件投递。
手动测试无误后,配置 Crontab 定时任务,实现 每周凌晨自动巡检、自动生成报告、自动推送邮箱,全程无人值守。
crontab -e
设置每周一凌晨 2 点执行巡检(资源消耗较低,建议在业务低峰期执行):
# 每周一凌晨2点自动执行服务器巡检
0 2 * * 1 /root/server_inspect.sh >/dev/null 2>&1
crontab -l
脚本依赖以下工具,执行前会自动检查并提示安装:
bcsysstatiproute2mailx脚本 CPU 负载风险判定逻辑为:5 分钟负载大于 CPU 逻辑核心数则告警,符合运维通用标准,可根据服务器业务压力自行调整阈值。
长期自动巡检会产生大量历史报告,建议搭配前文磁盘清理脚本,定期清理旧巡检日志,避免占用磁盘空间。
建议使用 root 用户运行,以避免部分信息因权限不足无法获取(如端口对应的进程名、系统日志等)。
外网邮箱推送失败,大概率是未配置 SMTP 中继、DNS 解析异常、SPF 策略拦截导致,本地邮件可正常推送属于正常现象。
部分开启 SELinux 或 AppArmor 的系统可能会拦截脚本的部分操作(如邮件发送、日志读取),若出现权限不足问题,可通过 audit.log 分析拒绝策略,按需配置放行规则,不建议长期直接关闭安全模块。
大概率是权限不足,建议使用 root 用户执行脚本;部分精简系统缺失依赖工具,按照脚本提示安装即可。
检查脚本路径是否为绝对路径、是否拥有执行权限、SELinux 是否拦截脚本执行,可通过 /var/log/cron 日志排查异常。
可以,脚本顶部配置项可自由修改 磁盘告警阈值、内存告警阈值,适配不同业务服务器标准。
如果你觉得本文对你有帮助,欢迎点赞、推荐、转发,关注我,后续会分享更多Linux入门干货!
文 / 零距技术仓
记录每一次真实的折腾 (#^.^#)
🚀 想看到更多实用折腾技巧?
👉 先关注
💬 评论区说说你的经历或想看的内容
👍 点赞表示支持
🔁 顺手分享给也在折腾的人,让大家都少踩坑 😎