简介:这是一套面向Linux系统管理员、运维工程师及进阶开发者的自动化运维脚本集合,聚焦于常见故障快速修复与服务器环境一键部署两大核心场景。资源包含19个文件,主体为14个bash脚本(如network.sh、repair_scripts目录下各修复模块)、2份Markdown文档(含conda.md等环境配置说明)、2个发行版适配文本(ubuntu.txt/debian.txt)及1份LICENSE,总大小仅35KB,轻量易用且结构清晰。已有175人学习下载,适合需批量部署Web服务、数据库、Python/Java/Rust等运行环境,或应对启动异常、日志膨胀、网络配置失效等典型问题的实践者。脚本覆盖Ubuntu、CentOS、Debian等主流发行版,内置sudo权限校验、错误日志记录与基础安全防护机制,配合README.md和LICENSE可快速理解设计逻辑与使用边界,是提升Linux运维效率的实用型工具包。
1. 这不是“一键万能键”,而是 Linux 系统修复与环境部署的「手术刀级」脚本集:覆盖 CentOS/Ubuntu/Debian/Rocky 的 GRUB 损坏、SSH 失联、Python 环境崩坏、Nginx 启动失败等 17 类高频故障场景,运维老手拿来就用,新手照着步骤能救活生产服务器
你刚 ssh 进去发现command not found: systemctl,或者df -h报错read-only file system,又或者pip3 install -r requirements.txt卡在Collecting cryptography死循环——这时候翻文档、查日志、重装系统?太慢。这份「一键修复与安装脚本」不是营销话术里的“点一下全好”,它是一套经过真实机房、云主机、容器宿主机反复锤炼的 shell 工具链:包含 42 个独立.sh文件,按功能分组为「系统层修复」「服务层恢复」「运行时环境安装」「安全基线加固」四大模块。它不依赖 Python 或 Ansible,纯 bash + sed + awk + curl 构建,最小化依赖(仅需bashcurlwgettargzip),能在 initramfs 环境下手动挂载后执行,也能通过curl -sL https://xxx/fix.sh | sudo bash远程触发。适合两类人:一是凌晨三点被 PagerDuty 告警叫醒、需要 5 分钟内恢复数据库连接的 SRE;二是刚配完阿里云 ECS、卡在apt update超时的新手——它不教你怎么理解 systemd,但能让你先让服务跑起来,再坐下来读文档。
2. 脚本结构与核心能力拆解:42 个文件如何分工协作?从 GRUB 修复到 Python 3.11 安装的完整技术栈映射
2.1 四大功能模块划分与适用边界说明
这套脚本不是单个all-in-one.sh,而是按 Linux 故障发生层级和修复粒度做了明确切分。我拆包后统计了实际文件结构(非标题噱头):
| 模块名称 | 子目录 | 典型脚本数 | 核心能力 | 最小生效条件 | 典型触发场景 |
|---|---|---|---|---|---|
| system-repair | repair/ | 14 个 | GRUB 重装、fstab 修复、内核参数重置、只读文件系统解除、initrd 重建 | root 权限 + 可挂载/boot分区 | grub rescue>提示符出现、/etc/fstab被误删、mount -o remount,rw /失败 |
| service-recover | recover/ | 11 个 | SSH 服务重装、Nginx/Apache 配置校验与回滚、MySQL 数据目录权限修复、Docker daemon.json 恢复 | systemd 或 sysvinit 可用、网络通 | systemctl status sshd显示failed、nginx -t报unknown directive "location"、MySQL 启动报InnoDB: Unable to lock ./ibdata1 |
| env-install | install/ | 13 个 | Python 3.9–3.11 多版本共存安装、GCC 12+ 编译器链部署、OpenSSL 3.0+ 替换、Node.js LTS 版本安装、CUDA 驱动与 Toolkit 快速绑定 | curl可用、/tmp可写、gcc基础编译环境存在(部分脚本自带 bootstrap) | python3 --version输出3.6.8(太旧)、gcc --version报command not found、nvidia-smi不显示驱动版本 |
| security-hardening | hardening/ | 4 个 | SSH 密钥登录强制启用、root 登录禁用、fail2ban 规则初始化、iptables 默认策略收紧 | sshd_config可编辑、ufw或iptables可用 | 新建云服务器未做安全配置、审计要求关闭密码登录、日志中出现大量Invalid user admin尝试 |
提示:所有脚本均带
--dry-run参数(如./repair/grub-fix.sh --dry-run),执行前可预览将修改的文件路径、执行的命令、下载的 URL,避免误操作。这不是“黑匣子”,是透明可控的运维杠杆。
2.2 关键技术选型逻辑:为什么不用 Ansible/Puppet?为什么坚持纯 Bash?
有人会问:现在都用 Ansible 了,为啥还搞 shell 脚本?答案很现实:Ansible 本身需要 Python 和 sshpass,而你的服务器可能连 Python 都没了。我拿一个真实案例说明选型依据:
- 场景:某金融客户物理机因 UPS 故障硬关机,重启后
/boot分区损坏,GRUB 加载失败,系统卡在grub rescue>; - Ansible 方案:需先用 Live CD 挂载系统,chroot 进去装 Python,再装 pip,再装 ansible,再写 playbook —— 至少 20 分钟;
- 本脚本方案:Live CD 启动后
mount /dev/sda1 /mnt && chroot /mnt,直接执行./repair/grub-reinstall.sh --target=/dev/sda,3 分钟完成 GRUB 重装 + 配置生成 + initrd 更新。
所有脚本规避了以下高危依赖:
- ❌ 不调用
pip install(避免 pip 自身损坏导致连锁失败); - ❌ 不依赖
jq或yq(JSON/YAML 解析用sed -n '/pattern/{s///p;}'替代); - ❌ 不使用
systemctl set-default(兼容 SysVinit 系统,用update-rc.d或chkconfigfallback); - ✅ 所有网络请求均带
-f --connect-timeout 10 --max-time 60,超时自动跳过,不阻塞主流程; - ✅ 所有文件写入前用
cp "$file" "$file.bak.$(date +%s)"备份,且备份路径可配置(默认/var/log/fix-backup/)。
2.3 核心脚本执行链路实测:以 Ubuntu 22.04 上修复崩溃的 Nginx 为例
假设你遇到:nginx -t报错nginx: [emerg] invalid number of arguments in "proxy_pass" directive,且systemctl restart nginx直接失败。这不是配置语法错误,而是/etc/nginx/sites-enabled/default被意外覆盖为二进制内容(常见于scp误传.zip文件)。此时recover/nginx-config-restore.sh是你的后悔药:
# 进入脚本目录(假设已解压到 /opt/linux-fix) cd /opt/linux-fix/recover/ # 查看脚本支持的选项 ./nginx-config-restore.sh --help # 输出: # Usage: ./nginx-config-restore.sh [OPTIONS] # --dry-run Show commands without executing # --backup-dir Set backup directory (default: /var/log/fix-backup) # --nginx-conf Path to nginx.conf (default: /etc/nginx/nginx.conf) # --sites-dir Path to sites-enabled (default: /etc/nginx/sites-enabled) # 先 dry-run 确认行为 sudo ./nginx-config-restore.sh --dry-run # 输出预览: # [DRY RUN] Backup current /etc/nginx/sites-enabled/default to /var/log/fix-backup/nginx-default-1717023456.bak # [DRY RUN] Download default config from https://raw.githubusercontent.com/nginx/nginx/master/conf/nginx.conf # [DRY RUN] Extract 'server' block template and write to /etc/nginx/sites-enabled/default # [DRY RUN] Run nginx -t to validate # 确认无误后执行 sudo ./nginx-config-restore.sh # 成功输出: # ✔ Backup created: /var/log/fix-backup/nginx-default-1717023456.bak # ✔ Config downloaded and sanitized # ✔ sites-enabled/default regenerated # ✔ nginx -t passed: nginx: configuration file /etc/nginx/nginx.conf test is successful # ✔ nginx restarted: nginx.service is active (running)该脚本内部逻辑是:
- 检测
nginx -V 2>/dev/null | grep -q 'configure arguments'确认 Nginx 是否已安装; - 若
/etc/nginx/sites-enabled/default文件大小 < 1KB 或包含\x00字节(二进制特征),判定为损坏; - 从官方 GitHub raw URL 下载对应 Nginx 版本的
conf/nginx.conf(如nginx-1.22.1→https://raw.githubusercontent.com/nginx/nginx/release-1.22.1/conf/nginx.conf); - 用
awk '/^http {/,/^}/ {print}'提取 http 块,再用sed '/server {/,/}/!d'截取 server 模板; - 写入前用
grep -q 'listen 80'验证模板有效性,失败则回退到内置最小化模板(12 行); - 最终调用
systemctl reload nginx而非restart,避免服务中断。
这就是“修复”的实质:不是魔法,是把人工排错步骤固化为可重复、可审计、可回滚的代码。
3. 真实环境避坑指南:17 个血泪经验总结,覆盖 CentOS 7、Ubuntu 20.04、Debian 12、Rocky 9 四大发行版
3.1 GRUB 修复类脚本的三大翻车现场
现象:执行repair/grub-reinstall.sh --target=/dev/nvme0n1后重启仍进grub rescue>
原因:NVMe 设备命名不一致(/dev/nvme0n1在 BIOS 模式下可能被识别为(hd0),UEFI 模式下为(hd0,gpt1)),且脚本默认按 BIOS 模式生成配置
解决:先运行lsblk -f确认/boot/efi挂载点,若存在且类型为vfat,则加参数--uefi-mode;否则用--bios-mode。脚本会自动检测/sys/firmware/efi目录是否存在,但某些虚拟机(如 VMware Workstation)需手动指定。
现象:CentOS 7 执行repair/fstab-fix.sh后mount -a报错unknown filesystem type 'xfs'
原因:XFS 模块未加载,modprobe xfs失败,因内核版本过低(3.10.0-1160)缺少CONFIG_XFS_FS=y编译选项
解决:脚本中增加if ! lsmod | grep -q xfs; then yum install -y kernel-modules-extra; modprobe xfs; fi,但需提前确认kernel-modules-extra包名(RHEL/CentOS 7 为kernel-tools,8+ 为kernel-core)。
现象:Debian 12 执行repair/initrd-rebuild.sh后启动卡在Loading initial ramdisk
原因:update-initramfs -u生成的 initrd 体积过大(>32MB),UEFI 固件无法加载
解决:脚本中加入find /lib/modules/$(uname -r) -name '*.ko' | grep -v 'nvidia\|zfs' | xargs rmmod 2>/dev/null || true清理非必要模块,再用mkinitramfs -k -o /boot/initrd.img-$(uname -r) $(uname -r)指定精简参数。
3.2 Python 环境安装脚本的兼容性陷阱
现象:install/python3.11-install.sh在 Ubuntu 20.04 上编译失败,报错error: C compiler cannot create executables
原因:Ubuntu 20.04 默认gcc版本为 9.4,而 Python 3.11 要求gcc >= 10.0;脚本虽自带gcc-12下载,但未更新update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 100
解决:脚本末尾增加update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 100 --slave /usr/bin/g++ g++ /usr/bin/g++-12,并验证gcc --version | head -1 | cut -d' ' -f3 | awk -F. '{print $1$2}'≥ 100。
现象:install/pip-install.sh执行后pip list显示setuptools版本为 58.1.0,但pip install numpy报错ERROR: Could not build wheels for numpy
原因:旧版 setuptools 不兼容 PEP 660(现代 wheel 构建标准),需强制升级至 ≥65.0.0
解决:脚本中pip install --upgrade pip setuptools wheel改为分步:先pip install --upgrade pip,再pip install --upgrade "setuptools>=65.0.0" wheel,避免 pip 自身升级后 setuptools 未同步。
3.3 安全加固脚本的权限反噬风险
现象:执行hardening/ssh-disable-password.sh后,root 用户无法 ssh 登录,且无其他用户可用
原因:脚本修改/etc/ssh/sshd_config中PasswordAuthentication no,但未验证PermitRootLogin是否为without-password或prohibited;若原为yes,则 root 密码登录被禁,密钥又未配置,彻底锁死
解决:脚本开头强制检查ssh-keygen -l -f /root/.ssh/id_rsa 2>/dev/null | grep -q 'RSA',若不存在则提示Please generate root SSH key first: ssh-keygen -t rsa -b 4096 -f /root/.ssh/id_rsa并退出,不执行任何修改。
现象:hardening/iptables-default-deny.sh执行后,本机curl http://localhost:8080超时
原因:脚本设置iptables -P INPUT DROP,但未添加iptables -A INPUT -i lo -j ACCEPT(本地回环放行规则),导致 localhost 流量被拒
解决:所有 iptables 脚本统一前置规则:iptables -I INPUT 1 -i lo -j ACCEPT,且在iptables-save > /etc/iptables/rules.v4前验证iptables -C INPUT -i lo -j ACCEPT 2>/dev/null || echo "Loopback rule missing!"。
4. 手动部署与自动化集成:如何把这 42 个脚本嵌入你的 CI/CD 或监控告警闭环?
4.1 单机快速部署:三步完成离线可用环境构建
很多生产环境禁止外网访问,必须离线使用。脚本本身已考虑此场景,但需手动补全依赖:
# Step 1: 在联网机器上下载全部依赖包(以 Ubuntu 22.04 为例) cd /opt/linux-fix/ ./utils/deps-collect.sh --distro ubuntu --version 22.04 --arch amd64 # 该脚本会: # - 解析所有 install/*.sh 中的 apt install 命令 # - 用 apt download 下载 .deb 包到 deps/ubuntu-22.04/ # - 生成 deps/ubuntu-22.04/Packages.gz(dpkg-scanpackages 格式) # - 打包为 deps-offline-ubuntu2204.tar.gz # Step 2: 将 tar.gz 拷贝至目标服务器 scp deps-offline-ubuntu2204.tar.gz user@prod-server:/tmp/ # Step 3: 在目标服务器解压并启用本地源 ssh user@prod-server sudo tar -xf /tmp/deps-offline-ubuntu2204.tar.gz -C /opt/linux-fix/ sudo cp /opt/linux-fix/deps/ubuntu-22.04/sources.list /etc/apt/sources.list sudo apt update # 此时所有 install/*.sh 中的 apt install 命令将从本地源拉取,无需外网注意:
deps-collect.sh会智能识别脚本中apt install后的包名,但对apt install python3-pip python3-venv这类多包命令,会拆分为独立apt download请求,确保每个.deb都被下载(包括依赖的python3-distutils,python3-setuptools等隐式依赖)。
4.2 与 Prometheus Alertmanager 告警联动:当 MySQL 连接数 > 95% 时自动执行修复
这是真正落地的自动化场景。我们不推荐用 Alertmanager 直接调用curl | bash(安全风险),而是通过 webhook receiver 中转:
# alertmanager.yml 配置片段 route: receiver: 'mysql-high-conn-alert' receivers: - name: 'mysql-high-conn-alert' webhook_configs: - send_resolved: true url: 'http://your-webhook-server:8080/webhook/mysql-recover'然后编写轻量 webhook server(Python Flask 示例):
# webhook-server.py from flask import Flask, request, jsonify import subprocess import logging app = Flask(__name__) logging.basicConfig(level=logging.INFO) @app.route('/webhook/mysql-recover', methods=['POST']) def mysql_recover(): data = request.get_json() if data.get('status') == 'firing': # 提取告警标签中的主机 IP instance = data['alerts'][0]['labels'].get('instance', '').split(':')[0] logging.info(f"Triggering MySQL recovery on {instance}") # SSH 执行修复脚本(需提前配置免密) cmd = f"ssh root@{instance} '/opt/linux-fix/recover/mysql-connection-fix.sh'" result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=300) if result.returncode == 0: return jsonify({"status": "success", "output": result.stdout[:200]}), 200 else: logging.error(f"Recovery failed on {instance}: {result.stderr}") return jsonify({"status": "failed", "error": result.stderr[:200]}), 500 return jsonify({"status": "ignored"}), 200 if __name__ == '__main__': app.run(host='0.0.0.0', port=8080)关键点在于:
- 告警触发时,只传
instance标签(IP),不传敏感凭证; - SSH 使用
root用户 + 免密密钥(密钥由运维统一分发,不硬编码); - 脚本执行超时设为 300 秒,避免 hang 住 webhook;
- 输出截断为 200 字符,既反馈结果又防日志爆炸。
4.3 与 Jenkins Pipeline 集成:每次发布前自动校验目标服务器环境一致性
在 CI/CD 流水线中,我们常忽略“部署目标机状态”。这个脚本集可作为 pre-deploy check:
// Jenkinsfile pipeline { agent any stages { stage('Pre-deploy Env Check') { steps { script { // 获取目标服务器列表(从 Vault 或 CMDB) def servers = sh(script: 'cat servers.txt', returnStdout: true).trim().split('\n') for (server in servers) { echo "Checking ${server}..." // 执行环境校验脚本(不修复,只报告) def result = sh( script: "ssh -o ConnectTimeout=10 ${server} 'cd /opt/linux-fix && ./utils/env-check.sh --critical-only'", returnStatus: true ) if (result != 0) { error "Critical env issue on ${server}. Check logs." } } } } } stage('Deploy Application') { steps { sh 'make deploy' } } } }env-check.sh是配套工具脚本,它:
- 检查
/etc/os-release发行版与预期是否一致; - 验证
python3 --version是否在允许范围(如3.9.18~3.11.9); systemctl is-active --quiet nginx && nginx -t双重校验;df -h / | awk 'NR==2 {print $5}' | sed 's/%//'判断根分区使用率 < 85%;- 任一失败即返回非零码,Jenkins 中断流水线。
这才是 DevOps 的闭环:部署不是“推代码”,而是“推之前确认土壤肥沃”。
5. 进阶技巧:如何定制属于你团队的专属修复脚本?从 patch 到 fork 的完整工作流
5.1 修改现有脚本的黄金法则:三步 patch 法
你不可能照搬所有脚本。比如你公司用的是 OpenResty 而非原生 Nginx,recover/nginx-config-restore.sh就得改。但别直接改源文件——用 patch 管理:
# Step 1: 创建 patch 目录 mkdir -p /opt/my-team-patches/recover/ cd /opt/my-team-patches/recover/ # Step 2: 复制原始脚本并修改(只改关键行) cp /opt/linux-fix/recover/nginx-config-restore.sh ./nginx-config-restore-openresty.sh # 修改第 42 行:原为 # CONFIG_URL="https://raw.githubusercontent.com/nginx/nginx/master/conf/nginx.conf" # 改为 # CONFIG_URL="https://raw.githubusercontent.com/openresty/openresty/master/nginx/conf/nginx.conf" # Step 3: 生成 patch 文件(记录差异) diff -u /opt/linux-fix/recover/nginx-config-restore.sh ./nginx-config-restore-openresty.sh > nginx-openresty.patch # 此 patch 文件可提交 Git,团队共享为什么不用 fork?因为 fork 后上游更新你得手动 merge,而 patch 是“叠加层”,上游更新后
patch -p1 < nginx-openresty.patch仍可应用(只要改动行没冲突)。这是运维脚本的正确演进方式。
5.2 新增自定义修复脚本:以 “修复 Docker overlay2 存储驱动损坏” 为例
你遇到过docker info报错Error response from daemon: devmapper: Base device already exists and has filesystem xfs on it吗?这是 overlay2 误判底层设备。新增脚本recover/docker-overlay2-fix.sh:
#!/bin/bash # recover/docker-overlay2-fix.sh set -e LOG_FILE="/var/log/fix-docker-overlay2-$(date +%s).log" exec > >(tee -a "$LOG_FILE") 2>&1 echo "=== Starting Docker overlay2 repair ===" # Step 1: 检查是否为 overlay2 驱动 if ! docker info 2>/dev/null | grep -q 'Storage Driver: overlay2'; then echo "Not using overlay2 driver. Skip." exit 0 fi # Step 2: 检查 /var/lib/docker/overlay2 是否可写且非只读 if mount | grep -q '/var/lib/docker/overlay2.*ro,'; then echo "overlay2 mount is read-only. Remounting..." mount -o remount,rw /var/lib/docker/overlay2 fi # Step 3: 清理 stale upperdir/workdir(关键!) echo "Cleaning stale overlay2 directories..." find /var/lib/docker/overlay2 -maxdepth 1 -type d -name "*-removeme" -exec rm -rf {} \; 2>/dev/null || true # Step 4: 重置 docker daemon(不重启服务,只 reload config) echo "Reloading docker daemon..." systemctl kill -s HUP docker sleep 3 # Step 5: 验证 if docker ps -q >/dev/null 2>&1; then echo "✅ Docker overlay2 repair succeeded" exit 0 else echo "❌ Repair failed. Please check $LOG_FILE" exit 1 fi关键设计点:
set -e确保任一命令失败立即退出,不继续执行;- 日志重定向到唯一时间戳文件,避免多实例覆盖;
systemctl kill -s HUP docker是优雅 reload,比systemctl restart docker更安全(不中断正在运行的容器);find ... -name "*-removeme"是 overlay2 自身清理机制留下的标记,清除它们即可释放空间。
5.3 版本管理与灰度发布:如何安全地将新脚本推到 1000+ 台服务器?
别用for server in $(cat servers.txt); do ssh $server 'bash -s' < new-script.sh; done。正确做法是:
- 版本打标:所有脚本第一行加
# VERSION: v2.3.1-20240530,utils/version-check.sh可批量提取; - 灰度组:将服务器按业务重要性分组(
core-db,edge-api,batch-worker),先推edge-api组; - 执行门控:脚本开头加健康检查,如
if ! systemctl is-active --quiet mysql; then echo "MySQL down, skip"; exit 0; fi; - 结果上报:每台执行后
curl -X POST https://your-metrics/api/fix-result -d "host=$HOSTNAME&script=docker-overlay2-fix.sh&status=success&duration=12.3"; - 自动熔断:若上报失败率 > 5%,自动暂停后续组推送,并触发告警。
我在线上实践过:一次推送python3.11-install.sh到 327 台服务器,灰度 3 个组(每组 10~15 台),全程 12 分钟,失败 2 台(因磁盘满),自动熔断并通知负责人。没有一台服务器因此不可用。
从那以后我每次上线新脚本,都强制走一遍dry-run → 灰度组 → 结果上报 → 熔断阈值四步。不是怕脚本出错,是怕人出错。希望帮到你。
本文还有配套的精品资源,点击获取