哈喽,兄弟们好,我是阿然。
咱们搞运维的,最怕听到哪句话?不是“服务器宕机了”,而是周五下午四点半,老板突然来一句:“阿然,把线上那 100 台服务器的健康状况整理个 Excel 报表给我,下班前要。”
手动一台台登录、敲命令、截图、填表……这哪是运维,这是“表哥”啊!
这次不整虚的,Bash 脚本 + Python 自动报表 + Ansible 批量并发,一套组合拳,直接把服务器巡检这件事彻底搞定!
运维人的原则是:能用脚本绝不手动,能自动化绝不人肉。
话不多说,直接上干货!👇
在服务器终端直接复制并执行以下命令(自动创建文件并赋权):
cat > syscheck.sh << 'EOF'#!/bin/bash# ================ SysCheck 2.0 服务器运维巡检脚本 ================# 更新日志:SysCheck 2.0 - 修复 Rocky Linux 安全检查报错,优化输出体验# 公众号:Linux运维进阶之路 | 作者:阿然# ===============================================================# --- 基础配置 ---# 自动检测终端颜色if [ -t 1 ]; then RED="\033[91m" GREEN="\033[92m" YELLOW="\033[93m" BLUE="\033[94m" BOLD="\033[1m" NC="\033[0m"else RED=""; GREEN=""; YELLOW=""; BLUE=""; BOLD=""; NC=""fiprint_title() {echo -e "\n${BLUE}${BOLD}════════════════════════════════════════════════════════════${NC}"echo -e "${BOLD}$1${NC}"echo -e "${BLUE}${BOLD}════════════════════════════════════════════════════════════${NC}"}print_status() {case"$1"in ok) echo -e "${GREEN} [OK] $2${NC}" ;; warn) echo -e "${YELLOW} [WARN] $2${NC}" ;; error) echo -e "${RED} [ERROR] $2${NC}" ;; info) echo -e "${BLUE} [INFO] $2${NC}" ;;esac}# --- 1. 系统基础信息 ---clearprint_title "Linux 服务器深度巡检 (SysCheck 2.0)"echo -e "巡检时间:$(date '+%Y-%m-%d %H:%M:%S')"[ -f /etc/os-release ] && . /etc/os-releaseprint_status info "系统版本 : ${PRETTY_NAME:-未知}"print_status info "主机名称 : $(hostname)"print_status info "内核版本 : $(uname -r)"print_status info "平均负载 : $(uptime | awk -F'load average:' '{print $2}' | sed 's/^[ \t]*//')"# --- 2. 资源使用情况 ---print_title "资源使用情况"# 内存mem_total=$(free -h | awk '/Mem/{print $2}')mem_used=$(free -h | awk '/Mem/{print $3}')mem_free=$(free -h | awk '/Mem/{print $4}')print_status info "内存总量: $mem_total | 已用: $mem_used | 剩余: $mem_free"# 磁盘 (排除 tmpfs, cdrom, loop, overlay)df -hT | grep -vE 'tmpfs|cdrom|loop|overlay' | whileread fs type size used avail use mount; do usage_num=$(echo"$use" | tr -d '%')if [ "$usage_num" -ge 90 ]; then print_status error "磁盘告警: $mount ($use) - 空间严重不足!"elif [ "$usage_num" -ge 80 ]; then print_status warn "磁盘预警: $mount ($use) - 空间较少"else print_status ok "磁盘正常: $mount ($use)"fidone# --- 3. 安全补丁检查 (修复增强版) ---print_title "安全补丁与漏洞检查"ifcommand -v apt >/dev/null 2>&1; then# Debian/Ubuntu 逻辑if updates=$(apt list --upgradable 2>/dev/null | grep -v "Listing..."); then cnt=$(echo"$updates" | wc -l)if [ "$cnt" -gt 0 ]; then print_status warn "发现 $cnt 个可升级包"else print_status ok "系统软件包已是最新"fifielifcommand -v dnf >/dev/null 2>&1 || command -v yum >/dev/null 2>&1; then# RHEL/CentOS/Rocky 逻辑 (增加容错) PKG_MGR=$(command -v dnf || command -v yum)# 核心修复:静默检查并捕获错误码# 如果源不支持 security 插件,此处不再报错退出,而是提示跳过if sec_info=$($PKG_MGR updateinfo list security 2>/dev/null); then sec_count=$(echo"$sec_info" | grep -c "security" || echo 0)if [ "$sec_count" -gt 0 ]; then print_status warn "发现 $sec_count 个安全补丁待安装!"echo"$sec_info" | head -n 5else print_status ok "未发现严重安全补丁"fielse print_status info "跳过安全检查:当前源不支持元数据查询或缺少插件"fielse print_status info "未知包管理器,跳过补丁检查"fi# --- 4. 异常检测 ---print_title "异常进程检测 (Top 3)"# 高负载进程echo -e "${BOLD}CPU 占用前三:${NC}"ps -eo pid,user,%cpu,cmd --sort=-%cpu | head -n 4 | tail -n 3 | awk '{printf " %-6s %-10s %-6s %s\n", $1, $2, $3, $4}'echo -e "\n${BOLD}内存 占用前三:${NC}"ps -eo pid,user,%mem,cmd --sort=-%mem | head -n 4 | tail -n 3 | awk '{printf " %-6s %-10s %-6s %s\n", $1, $2, $3, $4}'# 僵尸进程zombies=$(ps -A -o stat,ppid,pid,cmd | grep -e '^[Zz]' | wc -l)if [ "$zombies" -gt 0 ]; then print_status error "发现 $zombies 个僵尸进程!"else print_status ok "无僵尸进程"fi# --- 5. 结束 ---print_title "巡检完成"echo -e "建议:定期清理 /var/log,关注磁盘使用率。\n"EOF# 赋予权限并运行chmod +x syscheck.sh./syscheck.sh

终端输出适合我们自己排查问题,但如果要给领导做月度/季度汇报,一份专业的 Excel 表格 才是加分项。
阿然给兄弟们写了一个 Python 脚本,它会自动采集系统信息,生成包含“系统概览”和“磁盘详情”两个 Sheet 的报表。
#!/usr/bin/env python3# -*- coding: utf-8 -*-# ==============================================================================# 脚本名称: syscheck_excel.py (Pro版)# 功能描述: 采集Linux系统信息、磁盘、Top进程,生成带样式的美观Excel报表# 运行方式: chmod +x syscheck_excel.py && ./syscheck_excel.py# 依赖库 : pip3 install psutil pandas openpyxl# 作者 : 阿然 @ Linux运维进阶之路# ==============================================================================import osimport sysimport socketimport datetimeimport platform# 依赖库检查try: import psutil import pandas as pd from openpyxl.styles import Font, PatternFill, Border, Side, Alignment from openpyxl.utils import get_column_letterexcept ImportError as e:print(f"\033[91m[Error] 缺少必要模块: {e.name}\033[0m")print("请先执行安装: pip3 install psutil pandas openpyxl") sys.exit(1)def get_size(bytes, suffix="B"):"""人性化显示文件大小""" factor = 1024for unit in ["", "K", "M", "G", "T", "P"]:if bytes < factor:return f"{bytes:.2f}{unit}{suffix}" bytes /= factordef get_process_info():"""获取CPU和内存占用最高的Top 10进程""" procs = []for p in psutil.process_iter(['pid', 'name', 'username', 'cpu_percent', 'memory_percent']): try: procs.append(p.info) except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess): pass# 转为DataFrame df_proc = pd.DataFrame(procs)if not df_proc.empty:# 按内存使用率排序取Top 10 df_proc = df_proc.sort_values(by='memory_percent', ascending=False).head(10) df_proc['cpu_percent'] = df_proc['cpu_percent'].apply(lambda x: f"{x:.1f}%") df_proc['memory_percent'] = df_proc['memory_percent'].apply(lambda x: f"{x:.1f}%") df_proc.columns = ['PID', '进程名', '用户', 'CPU使用率', '内存使用率']return df_procreturn pd.DataFrame()def beautify_excel(writer, sheet_name, df):"""Excel美化函数:调整列宽、设置边框、颜色高亮""" workbook = writer.book worksheet = writer.sheets[sheet_name]# 定义样式 header_fill = PatternFill(start_color="4F81BD", end_color="4F81BD", fill_type="solid") # 蓝色表头 header_font = Font(color="FFFFFF", bold=True) # 白色粗体字 thin_border = Border(left=Side(style='thin'), right=Side(style='thin'), top=Side(style='thin'), bottom=Side(style='thin')) align_center = Alignment(horizontal='center', vertical='center')# 告警样式 red_font = Font(color="FF0000", bold=True) # 红色警告 orange_font = Font(color="FFC000", bold=True) # 橙色预警# 1. 设置表头样式for cell in worksheet[1]: cell.fill = header_fill cell.font = header_font cell.alignment = align_center cell.border = thin_border# 2. 设置内容样式 & 自动列宽for col in worksheet.columns: max_length = 0 column = col[0].column_letter # 获取列号字母for cell in col:# 设置边框和居中 cell.border = thin_border cell.alignment = align_center# 计算最大列宽 try:if len(str(cell.value)) > max_length: max_length = len(str(cell.value)) except: pass# 3. 磁盘使用率高亮逻辑 (仅针对磁盘页面的"使用率"列)if sheet_name == '磁盘详情' and '使用率'in df.columns:# 找到"使用率"所在的列索引 usage_col_idx = df.columns.get_loc('使用率') + 1 if cell.col_idx == usage_col_idx and isinstance(cell.value, str) and '%'in cell.value: try: val = float(cell.value.strip('%'))if val >= 90: cell.font = red_fontelif val >= 80: cell.font = orange_font except ValueError: pass# 应用列宽 (稍微多给点余量) adjusted_width = (max_length + 4) worksheet.column_dimensions[column].width = adjusted_widthdef sys_check_excel():print(f"[{datetime.datetime.now().strftime('%H:%M:%S')}] ⏳ 开始深度巡检...") host_name = socket.gethostname()# --- 1. 系统概览 --- uname = platform.uname() boot_time = datetime.datetime.fromtimestamp(psutil.boot_time()).strftime("%Y-%m-%d %H:%M:%S") load_avg = os.getloadavg() if hasattr(os, 'getloadavg') else"N/A"# Windows兼容处理 sys_data = [ {'指标': '主机名', '内容': host_name}, {'指标': '系统版本', '内容': f"{uname.system} {uname.release}"}, {'指标': '内核版本', '内容': uname.version}, {'指标': 'CPU逻辑核数', '内容': f"{psutil.cpu_count(logical=True)} 核"}, {'指标': '内存总量', '内容': get_size(psutil.virtual_memory().total)}, {'指标': '系统负载 (1/5/15)', '内容': str(load_avg)}, {'指标': '启动时间', '内容': boot_time}, {'指标': '采集时间', '内容': datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")} ] df_sys = pd.DataFrame(sys_data)# --- 2. 磁盘详情 --- disk_list = []for partition in psutil.disk_partitions():if'loop'in partition.device or 'docker'in partition.mountpoint or 'overlay'in partition.mountpoint: continue try: u = psutil.disk_usage(partition.mountpoint) disk_list.append({'文件系统': partition.device,'挂载点': partition.mountpoint,'类型': partition.fstype,'总容量': get_size(u.total),'已用': get_size(u.used),'可用': get_size(u.free),'使用率': f"{u.percent}%" }) except PermissionError:continue df_disk = pd.DataFrame(disk_list)# --- 3. Top 10 进程 ---print(f"[{datetime.datetime.now().strftime('%H:%M:%S')}] ⏳ 正在分析进程资源...") df_proc = get_process_info()# --- 4. 生成 Excel --- filename = f"深度巡检报告_{host_name}_{datetime.datetime.now().strftime('%Y%m%d')}.xlsx" try: with pd.ExcelWriter(filename, engine='openpyxl') as writer:# 写入 Sheet df_sys.to_excel(writer, sheet_name='系统概览', index=False) df_disk.to_excel(writer, sheet_name='磁盘详情', index=False)if not df_proc.empty: df_proc.to_excel(writer, sheet_name='Top10进程', index=False)# 应用美化 beautify_excel(writer, '系统概览', df_sys) beautify_excel(writer, '磁盘详情', df_disk)if not df_proc.empty: beautify_excel(writer, 'Top10进程', df_proc)print(f"\n✅ 巡检完成!")print(f"📊 报表已生成: \033[92m{os.path.abspath(filename)}\033[0m")print(f"💡 提示: 磁盘使用率 >80% 字体显示橙色,>90% 显示红色") except Exception as e:print(f"\n❌ 生成失败: {e}")if __name__ == "__main__": sys_check_excel()



机器太多?不想一台台 SSH 登录? 如果你有 Ansible 环境,只需要 3 步,就能把 100 台服务器的体检单全抓回来。
确保你的 Ansible 主机清单 (hosts.ini) 已经配置好:
[webservers]192.168.1.10192.168.1.11[dbservers]192.168.1.20check_all.yml)这个 Playbook 会自动把第一章的 Bash 脚本分发到所有服务器 -> 执行 -> 拉取结果到本地 reports 目录。
----name:全网服务器批量巡检hosts:allbecome:yestasks:-name:1.分发脚本copy:src:./syscheck.sh# 确保 syscheck.sh 在当前目录dest:/usr/local/bin/syscheck.shmode:'0755'-name:2.执行巡检shell:/usr/local/bin/syscheck.sh>/tmp/check_{{ansible_hostname}}.txt# 提示:如果不想看颜色乱码,可以在脚本里把颜色变量置空-name:3.拉取报告fetch:src:/tmp/check_{{ansible_hostname}}.txtdest:./reports/flat:yes-name:4.清理现场file:path:/tmp/check_{{ansible_hostname}}.txtstate:absentansible-playbook -i hosts.ini check_all.yml喝口水的功夫,打开 reports/ 文件夹,所有服务器的巡检结果整整齐齐地躺在那里。
很多兄弟问我:“运维做到最后是不是就是写脚本?”
我觉得,运维的核心价值在于“标准化”和“可观测性”。
希望今天的 SysCheck 能帮你从繁琐的重复劳动中解放出来,早点下班,多陪陪家人。
另外我给大家整理了一些技术资料有需要直接下载即可


链接:https://pan.quark.cn/s/bc5c2c2700f8
需要什么资料也可在评论区留言
或者添加小编咨询

1、告别单点故障!Linux双网卡绑定实战,让故障自动“绕行”
2、Linux服务器太慢?8个系统优化技巧让性能飙升(运维必看)
看完本文有收获?请分享给更多人
推荐关注「Linux 运维进阶之路」,提升Linux技能
