作为Linux运维人,批量管理多台服务器是日常高频工作——每天手动登录每台服务器查看CPU、内存、磁盘状态,不仅耗时耗力,还容易遗漏异常。更麻烦的是,查到异常后还要手动整理状态、发送通知,效率极低。今天就分享一个实用的Shell脚本实操教程,既能批量查看多台Linux服务器状态,还能自动将状态报告发送到指定邮箱,全程自动化,帮你节省80%的时间!在编写、执行脚本前,需要先完成3个简单的前置配置,确保脚本能正常运行、邮件能顺利发送。因为要批量查看多台服务器,为了避免每次登录都输入密码,需要配置“免密登录”,脚本才能自动登录每台服务器获取状态。ssh-keygen -t rsassh-copy-id root@192.168.1.101ssh-copy-id root@192.168.1.102
注意:如果目标服务器用户名不是root,替换成对应的用户名2.安装邮件发送工具(postfix+mailx)脚本需要通过mailx工具发送邮件,默认Linux系统可能未安装,执行以下命令安装:# CentOS系统安装yum install postfix mailx -y# Ubuntu系统安装apt-get install postfix mailx -y
安装完成后,简单配置邮件发送参数,这里以163邮箱为例:vi /etc/mail.rc# 在文件末尾添加以下内容set from=yhaiwen@163.comset smtp=smtp.163.comset smtp-auth-user=yhaiwen@163.comset smtp-auth-password=你的邮箱授权码(不是登录密码)set smtp-auth=login
测试邮件是否能正常发送:执行以下命令,若能收到邮件,说明配置成功。echo "测试邮件发送" | mailx -s "Shell脚本测试" yhaiwen@163.com
配置完成后,直接复制以下脚本,根据自己的服务器情况修改3处关键配置,即可执行。#!/bin/bash# 1. 配置需要检测的多台服务器IPSERVER_IP_LIST="192.168.1.101 192.168.1.102 192.168.1.103"# 2. 配置异常阈值CPU_THRESHOLD=80 MEM_THRESHOLD=80 DISK_THRESHOLD=85 # 3. 配置邮件信息SEND_MAIL="yhaiwen@163.com"RECEIVE_MAIL="yhaiwen@163.com"MAIL_SUBJECT="【服务器状态报告】$(date +%Y-%m-%d %H:%M:%S)"# -----------------------------------------------------------------------------# 定义邮件内容初始变量MAIL_CONTENT="服务器状态检测报告(检测时间:$(date +%Y-%m-%d %H:%M:%S))\n\n"# 循环遍历每台服务器,获取状态for IP in $SERVER_IP_LISTdo # 检测服务器是否能连通 ping -c 2 $IP > /dev/null 2>&1 if [ $? -ne 0 ]; then MAIL_CONTENT="${MAIL_CONTENT}服务器 $IP :无法连通\n\n" continue fi # 1. 获取CPU使用率 CPU_USAGE=$(ssh $IP "top -bn1 | grep 'Cpu(s)' | sed 's/.*, *\([0-9.]*\)%* id.*/\1/' | awk '{print 100 - $1}' | awk -F. '{print $1"."$2}'") CPU_STATUS="正常" if [ $(echo "$CPU_USAGE > $CPU_THRESHOLD" | bc) -eq 1 ]; then CPU_STATUS="CPU使用率过高" fi # 2. 获取内存使用率 MEM_TOTAL=$(ssh $IP "free -m | grep Mem | awk '{print $2}'") MEM_USED=$(ssh $IP "free -m | grep Mem | awk '{print $3}'") MEM_USAGE=$(echo "scale=1; $MEM_USED / $MEM_TOTAL * 100" | bc) MEM_STATUS="正常" if [ $(echo "$MEM_USAGE > $MEM_THRESHOLD" | bc) -eq 1 ]; then MEM_STATUS="内容使用率过高" fi # 3. 获取磁盘使用率 DISK_USAGE=$(ssh $IP "df -h / | grep '/' | awk '{print $5}' | sed 's/%//'") DISK_STATUS="正常" if [ $DISK_USAGE -gt $DISK_THRESHOLD ]; then DISK_STATUS="磁盘使用率过高" fi # 4. 获取网络状态 NET_IP=$(ssh $IP "ifconfig eth0 | grep 'inet ' | awk '{print $2}'") NET_IN=$(ssh $IP "ifstat -i eth0 1 1 | grep eth0 | awk '{print $1}'") NET_OUT=$(ssh $IP "ifstat -i eth0 1 1 | grep eth0 | awk '{print $2}'") # 将当前服务器状态添加到邮件内容中 MAIL_CONTENT="${MAIL_CONTENT}服务器IP:$IP 网卡IP:$NET_IP CPU使用率:$CPU_USAGE% 【$CPU_STATUS】 内存使用率:$MEM_USAGE% 【$MEM_STATUS】(总内存:${MEM_TOTAL}M,已用:${MEM_USED}M) 磁盘使用率(/):$DISK_USAGE% 【$DISK_STATUS】 网络流入:$NET_IN 网络流出:$NET_OUT --------------------------------------------------\n"done# 发送邮件(将邮件内容转换为中文编码,避免乱码)echo -e "$MAIL_CONTENT" | iconv -f UTF-8 -t GBK | mailx -s "$MAIL_SUBJECT" -r $SEND_MAIL $RECEIVE_MAIL# 脚本执行完成提示echo "服务器状态检测完成,邮件已发送至 $RECEIVE_MAIL,请查收!"echo "检测时间:$(date +%Y-%m-%d %H:%M:%S)"
vi batch_check_server_status.shchmod +x batch_check_server_status.sh./batch_check_server_status.sh
执行后,脚本会自动遍历每台服务器,获取状态,判断是否异常,最后将完整报告发送到指定邮箱,执行完成后会提示“邮件已发送”。
脚本执行成功后,终端会显示提示信息,同时接收邮箱会收到一封标题为“【服务器状态报告】+时间”的邮件,邮件内容清晰明了:正常服务器:所有状态标注“正常”,清晰显示CPU、内存、磁盘、网络信息;异常服务器:对应异常项标红提醒(如CPU使用率过高),一眼就能找到异常服务器;无法连通服务器:单独标注,提醒运维人员及时排查宕机或网络问题。问题1:脚本执行提示“ssh: connect to host xxx port 22: Connection refused” 解决方案:检查目标服务器SSH服务是否开启(systemctl start sshd),或服务器IP是否填写错误,确保网络能连通。解决方案:重新执行ssh-copy-id命令,确保控制端的公钥已成功复制到目标服务器。问题3:邮件发送失败,终端提示“send-mail: fatal: parameter inet_interfaces: no local interface found for ::1”解决方案:编辑postfix配置文件,将inet_interfaces = all 改为 inet_interfaces = localhost,保存后重启postfix。解决方案:脚本中已添加中文编码转换(iconv -f UTF-8 -t GBK),若仍乱码,检查接收邮箱的编码设置,或替换编码格式。问题5:无法获取网络流量,提示“ifstat: command not found”解决方案:安装ifstat工具,或修改脚本中网络流量获取命令。优化1:添加定时任务,每天自动执行脚本,定时发送状态报告(用crontab配置,如每天9点执行);优化2:添加更多检测项(如服务器负载、进程状态、端口开放情况)。