自动化巡检脚本编写:用 Shell 定时检查服务器磁盘、内存与端口
服务器日常巡检如果靠人工登录逐台敲命令,既慢又容易漏。
自动化巡检脚本编写的核心思路是:把需要反复检查的项目写进一个 Shell 脚本,用 crontab 定时跑,输出结果写入日志,异常时再通知你。
本文以 Linux 服务器为例,从零写一个能检查磁盘、内存、端口和关键服务状态的巡检脚本。
先确认环境和前提条件
开始写脚本之前,先确认几件事,否则后面容易卡在权限或命令不存在上。
- 操作系统:常见的 CentOS、Ubuntu、Debian 等发行版都可以,本文命令在 Bash 环境下通用。
- 登录方式:使用具有
sudo权限的普通用户,或直接使用 root,避免脚本执行时权限不足。 - 需要的基础命令:
df、free、ss、systemctl、awk、grep,这些通常在系统自带工具里。 - 确认 Bash 路径:执行
which bash,一般返回/bin/bash。
建议先创建脚本目录和日志目录,方便统一管理:
mkdir -p /opt/check
mkdir -p /var/log/check
后面的脚本放在 /opt/check/check.sh,日志写到 /var/log/check/。
编写巡检脚本的核心结构
一个实用的巡检脚本通常包含四部分:定义检查项、采集数据、判断阈值、输出结果。
下面是一个可以直接改用的示例。
#!/bin/bash
# 服务器基础巡检脚本
LOG_DIR="/var/log/check"
DATE=$(date +%F_%H%M%S)
LOG_FILE="${LOG_DIR}/check_${DATE}.log"
# 磁盘使用率阈值(百分比)
DISK_THRESHOLD=85
# 内存使用率阈值(百分比)
MEM_THRESHOLD=85
# 需要检查的端口
PORTS="22 80 443"
# 需要检查的服务
SERVICES="sshd nginx"
echo "===== 巡检开始 $(date '+%F %T') =====" >> "$LOG_FILE"
# 1. 磁盘检查
check_disk() {
df -hP | grep -vE '^Filesystem|tmpfs|cdrom' | while read -r line; do
usage=$(echo "$line" | awk '{print $5}' | tr -d '%')
mount=$(echo "$line" | awk '{print $6}')
if [ "$usage" -ge "$DISK_THRESHOLD" ]; then
echo "[警告] 挂载点 $mount 使用率 ${usage}%" >> "$LOG_FILE"
else
echo "[正常] 挂载点 $mount 使用率 ${usage}%" >> "$LOG_FILE"
fi
done
}
# 2. 内存检查
check_mem() {
mem_usage=$(free | awk '/Mem:/ {printf "%.0f", $3/$2*100}')
if [ "$mem_usage" -ge "$MEM_THRESHOLD" ]; then
echo "[警告] 内存使用率 ${mem_usage}%" >> "$LOG_FILE"
else
echo "[正常] 内存使用率 ${mem_usage}%" >> "$LOG_FILE"
fi
}
# 3. 端口检查
check_port() {
for p in $PORTS; do
if ss -tln | grep -q ":$p "; then
echo "[正常] 端口 $p 正在监听" >> "$LOG_FILE"
else
echo "[警告] 端口 $p 未监听" >> "$LOG_FILE"
fi
done
}
# 4. 服务检查
check_service() {
for s in $SERVICES; do
if systemctl is-active --quiet "$s"; then
echo "[正常] 服务 $s 运行中" >> "$LOG_FILE"
else
echo "[警告] 服务 $s 未运行" >> "$LOG_FILE"
fi
done
}
check_disk
check_mem
check_port
check_service
echo "===== 巡检结束 $(date '+%F %T') =====" >> "$LOG_FILE"
写完后赋予执行权限,先手动跑一次看结果:
chmod +x /opt/check/check.sh
/opt/check/check.sh
cat /var/log/check/check_*.log
如果日志里能看到磁盘、内存、端口、服务的检查记录,说明脚本主体已经可用。
用 crontab 让它定时自动执行
脚本能手动跑通后,再交给 crontab 定时执行。
编辑当前用户的定时任务:
crontab -e
加入一行,表示每天凌晨 2 点执行一次:
0 2 * * * /bin/bash /opt/check/check.sh >/dev/null 2>&1
保存后可以用 crontab -l 查看是否写入成功。
如果希望每 10 分钟检查一次端口,可以再加一条:
*/10 * * * * /bin/bash /opt/check/check.sh >/dev/null 2>&1
注意:crontab 不会继承你当前 shell 的环境变量,脚本里尽量使用绝对路径,避免出现命令找不到的情况。
容易踩的坑和对应处理
- 权限不足:脚本读取某些目录或执行
systemctl时可能报权限错误,确认执行用户有对应权限,或改用 root 的 crontab。 - 命令不存在:不同发行版里
ss可能未安装,可以用netstat替代,先执行which ss确认。 - 端口匹配不准:
grep ":$p "里的空格是为了避免匹配到像 2200 这种包含 22 的端口,如果你的环境端口写法不同,需要相应调整。 - 日志无限增长:长期定时执行会不断产生新日志文件,建议在脚本里加清理逻辑,或单独写一条定时删除旧日志的任务,例如保留最近 7 天。
- 阈值写死:磁盘、内存阈值直接写常量不利于维护,可以改成从配置文件读取,后续调整不用改脚本主体。
怎么验证脚本真的在正常工作
验证分两步:先看日志,再看定时任务是否触发。
- 查看最新日志:
ls -lt /var/log/check/找到最新文件,用tail -n 30查看内容。 - 确认 crontab 已生效:
crontab -l能看到你添加的行。 - 观察执行记录:
grep CRON /var/log/syslog(Debian/Ubuntu)或grep CRON /var/log/cron(CentOS)可以看到任务是否被调度。 - 模拟异常验证:临时把磁盘阈值改成 1,手动跑一次,看日志里是否出现
[警告],确认判断逻辑有效,验证完记得改回正常值。
如果日志里只有开始和结束标记,没有检查内容,多半是函数没被调用或命令路径有问题,回到脚本里逐段排查。
常见疑问
脚本必须用 Bash 写吗?
不是必须。
Bash 在 Linux 上最通用,零基础也容易上手。
如果你更熟悉 Python,也可以用 Python 写,逻辑一样,只是采集命令和判断方式换成对应写法。
巡检结果怎么通知到我?
最简单的方式是脚本发现异常时往日志里写标记,再用 grep 配合邮件或 webhook 发送。
也可以在脚本末尾判断日志里是否包含 [警告],有就调用通知命令。
具体通知方式取决于你现有的告警渠道。
脚本能检查多个服务器吗?
单机脚本只管本机。
如果要巡检多台服务器,通常的做法是在一台管理机上用 SSH 循环登录各台执行脚本,或者把脚本分发到每台机器各自执行、各自记录日志,再集中收集。
自动化巡检脚本编写并不复杂,关键是先把检查项和判断条件写清楚,再交给定时任务稳定运行。
建议你先在测试环境按本文步骤跑通,再逐步把阈值、检查项和通知方式调整成适合自己服务器的配置。