怎样实现系统环境检测脚本

wen 实用脚本 26

从零构建高可用自动化诊断工具

在当前复杂多变的IT基础设施中,系统环境检测脚本已成为运维工程师、开发人员及SRE工程师的必备利器,无论是部署前的环境预检、故障排查时的快速诊断,还是CI/CD流水线中的合规校验,一套健壮的检测脚本能够有效降低人为操作失误,提升自动化运维效率,如何从需求分析到代码落地,实现一套既准确又灵活的系统环境检测脚本?本文将为您拆解完整路径,并提供可复用的代码范式。

怎样实现系统环境检测脚本


📖 目录导读

  1. 理解核心需求:脚本应检测什么?

    硬件资源、操作系统版本、依赖服务、网络连通性

  2. 检测脚本的设计原则

    模块化、幂等性、可扩展性

  3. 关键技术实现:通用检测模块拆解

    配置管理、执行引擎、结果输出

  4. 实战代码示例:基于Shell的通用检测框架
  5. 常见Q&A:优化与排坑技巧
  6. 进阶:集成告警与CI/CD流水线

检测脚本的核心检测维度

在编写脚本前,必须明确“检测什么”,综合多套成熟方案,建议覆盖以下四大类:

  1. 硬件与内核环境
    • CPU核数、内存大小、磁盘使用率、系统负载(uname -afree -mdf -h
  2. 操作系统与软件版本
    • 系统发行版(cat /etc/os-release)、内核版本、必备命令是否安装(command -v
  3. 关键服务与端口状态
    • 数据库、Nginx、Redis等进程存活(ps aux | grep);端口监听(ss -tlnp
  4. 网络连通性与DNS解析
    • 外网连通性(pingcurl)、DNS获取A记录、指定端口的TCP连通性(nc -zv

设计原则小提示:脚本不应破坏环境,应保持只读检测,新增的文件或临时安装包必须清理。


模块化设计原则

为保证脚本的可维护性与复用性,建议遵循以下原则:

  • 配置分离:将检测阈值、主机列表、端口信息抽取至单独配置文件(如YAML或.env)。
  • 函数化封装:每个检测项成为独立函数,通过返回值或状态码判断通过/失败。
  • 结果标准化:输出格式统一,推荐JSON或表格形式,便于后续程序解析。
  • 幂等性:每次运行结果一致,不依赖之前的执行痕迹。
check_memory() {
    local threshold=${1:-80}    # 默认阈值80%
    local usage=$(free | awk '/Mem:/ {printf "%.0f", $3/$2 * 100}')
    if [ "$usage" -gt "$threshold" ]; then
        echo "FAIL: Memory usage ${usage}% > ${threshold}%"
        return 1
    else
        echo "PASS: Memory usage ${usage}%"
        return 0
    fi
}

关键技术实现拆解

一个完整的检测脚本包含三个核心执行阶段:

  1. 初始化阶段:加载配置、检查依赖命令是否存在。
  2. 执行阶段:依次运行所有检测函数,收集结果(可并行执行利用多核)。
  3. 报告阶段:汇总成功/失败/警告信息,输出汇总MD5校验或发送告警。

对于并行检测需求,使用xargs -Pwait &可实现加速;若需跨平台运行(Windows/Linux),则优先选择Python脚本中的platform模块。


实战代码示例:简明Shell检测框架

以下是一个可直接落地的检测框架,支持自定义配置和彩色输出:

#!/bin/bash
# 系统环境检测脚本 v2.0
set -euo pipefail
# 配置区
THRESHOLD_DISK=90
THRESHOLD_MEM=80
REQUIRED_CMD="curl nc awk free"
REQUIRED_SERVICE="sshd mysqld"  # 改用实际服务名
# 初始化:检查关键命令
init_check() {
    for cmd in $REQUIRED_CMD; do
        if ! command -v $cmd &>/dev/null; then
            echo "ERROR: $cmd not found. Abort."
            exit 1
        fi
    done
}
# 检测函数:磁盘
check_disk() {
    local usage=$(df / | awk 'NR==2 {print $5}' | sed 's/%//')
    if [ "$usage" -gt "$THRESHOLD_DISK" ]; then echo "FAIL: Disk / ${usage}%"; return 1; else echo "PASS: Disk / ${usage}%"; fi
}
# 检测函数:CPU负载
check_cpu() {
    local load=$(uptime | awk -F'load average:' '{print $2}' | cut -d, -f1 | sed 's/ //g')
    if (( $(echo "$load > $(nproc)" | bc -l) )); then echo "FAIL: CPU load $load > cores"; else echo "PASS: CPU load $load"; fi
}
# 检测函数:服务端口
check_port() {
    local port=3306
    if nc -zv 127.0.0.1 "$port" &>/dev/null; then echo "PASS: Port $port open"; else echo "FAIL: Port $port not reachable"; fi
}
# 主执行
main() {
    init_check
    echo "========== 环境检测开始 =========="
    check_disk
    check_cpu
    check_port
    echo "========== 检测完成 =========="
}
main "$@"

常见Q&A:优化与排坑技巧

Q1:检测脚本在执行时卡住很久怎么办?
A1: 网络检测(如nccurl)需设置超时,例如timeout 5 nc -zv host 80,并在脚本中捕获timeout返回码。

Q2:如何将脚本集成到Ansible或SaltStack?
A2: 脚本输出JSON格式结果,在配置管理工具中通过register变量读取(例如Ansible的shell模块并changed_when: false)。

Q3:生产环境中检测脚本可能泄露敏感端口信息吗?
A3: 建议使用日志分级(INFOWARNERROR),禁止输出IP/端口至标准输出;敏感检测项仅在调试模式下打印。

Q4:检测脚本跨平台兼容(Linux与macOS)?
A4: macOS缺乏nc-z参数,需用/dev/tcp重定向或改用Python的socket模块,推荐用uname -s做平台判断。


进阶:集成告警与CI/CD

  • 与Prometheus集成:脚本输出Key-Value格式暴露为Prometheus文本,配合node_exporter的textfile收集器。
  • 与Jenkins/GitLab CI集成:在流水线中直接调用脚本,根据返回值判定继续或中止构建。
    stages:
      - env_check
    environment_check:
      script: "./sys_check.sh"
      allow_failure: false
  • 告警通知:失败项通过mailx、Slack Webhook或钉钉机器人推送,实现无人值守。

抱歉,评论功能暂时关闭!