🔥 推荐理由:每次重装系统后都要手动备份、编辑 sources.list 或 CentOS-Base.repo,还要去网上找镜像源地址、匹配版本号……烦不烦?这个 Bash 脚本让你30 秒完成系统检测、镜像源选择、自动备份、一键替换,甚至支持自定义 URL——配置镜像源从此只需选数字!


📌 前言

在国内使用 Ubuntu 或 CentOS,第一件事就是换成国内镜像源,否则 apt update 或 yum makecache 慢到怀疑人生。
但是——

  • Ubuntu 要记住版本代号(focal、jammy…)

  • CentOS 要区分主版本号(7、8、9…),EOL 版本还要改用 vault

  • 还要手动备份原文件,万一写错了还能恢复

有没有一个脚本,让你像点菜一样选系统、选镜像源,然后自动完成一切?
有!今天分享的 configure_mirror.sh 就是为此而生。


✨ 脚本亮点

功能 说明
🔐 自动提权检测 如果不是 root 执行,直接提示退出,防止权限不足导致配置失败
🧠 智能系统识别 读取 /etc/os-release 自动检测当前系统,但仍允许手动选择目标系统(方便跨平台配置)
📋 主流镜像源内置 阿里云、清华大学、中科大、网易,一键切换;也支持自定义 URL
🎯 版本自动匹配 自动读取 Ubuntu 版本代号或 CentOS 主版本号,并询问确认,避免出错
💾 自动备份 修改前自动备份原文件(带时间戳),放心折腾,随时可恢复
⚙️ 生成标准配置 根据官方规范生成完整的 sources.list 或 CentOS-Base.repo,包含 main/updates/backports/security 等常用仓库
✅ 可选立即更新 配置完成后询问是否执行 apt update 或 yum makecache,不用再敲命令

🎬 效果预览

运行脚本(需 root):

sudo bash configure_mirror.sh

你会看到如下交互界面:

=========================================
       系统镜像源配置工具
=========================================
检测到当前系统可能为: Ubuntu
请选择你要配置的操作系统类型:
1) Ubuntu
2) CentOS / RHEL 系列
请输入选项 [1-2]: 1
你选择了: Ubuntu
=========================================
请选择要使用的镜像源:
1) 网易
2) 清华大学
3) 中国科学技术大学
4) 阿里云
5) 自定义URL
6) 退出
#? 4
你选择了镜像源: 阿里云 (http://mirrors.aliyun.com/ubuntu/)
检测到 Ubuntu 版本代号: jammy
是否使用该代号? [Y/n]: y
已备份原始源文件到: /etc/apt/sources.list.backup.20250612143022
Ubuntu 镜像源配置完成!
是否立即执行 apt update 更新软件包列表? [Y/n]: y
命中:1 http://mirrors.aliyun.com/ubuntu jammy InRelease
...
=========================================
镜像源配置脚本执行完毕。
如需恢复原始配置,请使用备份文件: /etc/apt/sources.list.backup.20250612143022

CentOS 用户同样简洁,脚本会自动处理 vault 等特殊情况。


🛠 如何使用

1️⃣ 环境要求

  • 操作系统:Ubuntu / CentOS / RHEL 系列(其他 Debian 系或 CentOS 衍生版也可尝试)

  • 必须具有 root 权限(脚本会检查)

  • 命令:bashcatseddate 等基础工具(几乎每台 Linux 都有)

2️⃣ 下载脚本

复制下面的完整代码,保存为 configure_mirror.sh

#!/bin/bash

# ============================================
# 脚本名称: configure_mirror.sh
# 功能: 交互式配置 Ubuntu / CentOS 系统镜像源
# 使用: sudo bash configure_mirror.sh
# ============================================

# 检查 root 权限
if [ "$EUID" -ne 0 ]; then
  echo "请使用 root 权限运行此脚本 (例如: sudo $0)"
  exit 1
fi

# 检测当前实际系统类型(用于自动提示,但仍允许用户手动选择)
detected_os=""
if [ -f /etc/os-release ]; then
  . /etc/os-release
  case "$ID" in
    ubuntu) detected_os="Ubuntu" ;;
    centos|rhel|rocky|almalinux) detected_os="CentOS" ;;
    *) detected_os="Unknown" ;;
  esac
fi

# 显示菜单让用户选择目标操作系统
echo "========================================="
echo "       系统镜像源配置工具"
echo "========================================="
if [ -n "$detected_os" ] && [ "$detected_os" != "Unknown" ]; then
  echo "检测到当前系统可能为: $detected_os"
fi
echo "请选择你要配置的操作系统类型:"
echo "1) Ubuntu"
echo "2) CentOS / RHEL 系列"
read -p "请输入选项 [1-2]: " os_choice

case $os_choice in
  1) TARGET_OS="Ubuntu" ;;
  2) TARGET_OS="CentOS" ;;
  *) echo "无效选择,退出。"; exit 1 ;;
esac
echo "你选择了: $TARGET_OS"

# 定义镜像源列表(名称及对应的 URL 模板)
declare -A mirrors
mirrors["阿里云"]=""
mirrors["清华大学"]=""
mirrors["中国科学技术大学"]=""
mirrors["网易"]=""

# 根据系统类型填充具体 URL
if [ "$TARGET_OS" = "Ubuntu" ]; then
  mirrors["阿里云"]="http://mirrors.aliyun.com/ubuntu/"
  mirrors["清华大学"]="https://mirrors.tuna.tsinghua.edu.cn/ubuntu/"
  mirrors["中国科学技术大学"]="https://mirrors.ustc.edu.cn/ubuntu/"
  mirrors["网易"]="http://mirrors.163.com/ubuntu/"
elif [ "$TARGET_OS" = "CentOS" ]; then
  mirrors["阿里云"]="http://mirrors.aliyun.com/centos/"
  mirrors["清华大学"]="https://mirrors.tuna.tsinghua.edu.cn/centos/"
  mirrors["中国科学技术大学"]="https://mirrors.ustc.edu.cn/centos/"
  mirrors["网易"]="http://mirrors.163.com/centos/"
fi

# 显示镜像源菜单
echo "========================================="
echo "请选择要使用的镜像源:"
select mirror_name in "${!mirrors[@]}" "自定义URL" "退出"; do
  if [ "$mirror_name" = "退出" ]; then
    echo "退出脚本。"
    exit 0
  elif [ "$mirror_name" = "自定义URL" ]; then
    read -p "请输入完整的镜像源基础URL (例如 http://mirrors.example.com/ubuntu/): " custom_url
    mirror_url="$custom_url"
    mirror_name="自定义"
    break
  elif [ -n "$mirror_name" ]; then
    mirror_url="${mirrors[$mirror_name]}"
    break
  else
    echo "无效选择,请重新选择。"
  fi
done

echo "你选择了镜像源: $mirror_name ($mirror_url)"

# ==================== Ubuntu 配置 ====================
if [ "$TARGET_OS" = "Ubuntu" ]; then
  # 检测 Ubuntu 版本代号
  if [ -f /etc/os-release ]; then
    . /etc/os-release
    UBUNTU_CODENAME="$VERSION_CODENAME"
  fi
  if [ -z "$UBUNTU_CODENAME" ]; then
    echo "无法自动检测 Ubuntu 版本代号,请手动输入 (例如 focal, bionic, jammy):"
    read -p "版本代号: " UBUNTU_CODENAME
  else
    echo "检测到 Ubuntu 版本代号: $UBUNTU_CODENAME"
    read -p "是否使用该代号? [Y/n]: " confirm
    if [[ "$confirm" =~ ^[Nn] ]]; then
      read -p "请输入正确的版本代号: " UBUNTU_CODENAME
    fi
  fi

  SOURCES_FILE="/etc/apt/sources.list"
  BACKUP_FILE="${SOURCES_FILE}.backup.$(date +%Y%m%d%H%M%S)"

  # 备份原文件
  cp "$SOURCES_FILE" "$BACKUP_FILE"
  echo "已备份原始源文件到: $BACKUP_FILE"

  # 生成新的 sources.list
  cat > "$SOURCES_FILE" <<EOF
# 由脚本自动生成,镜像源: $mirror_name
# 备份文件: $BACKUP_FILE

deb ${mirror_url} ${UBUNTU_CODENAME} main restricted universe multiverse
deb ${mirror_url} ${UBUNTU_CODENAME}-updates main restricted universe multiverse
deb ${mirror_url} ${UBUNTU_CODENAME}-backports main restricted universe multiverse
deb ${mirror_url} ${UBUNTU_CODENAME}-security main restricted universe multiverse

# 源码仓库 (如需取消注释)
# deb-src ${mirror_url} ${UBUNTU_CODENAME} main restricted universe multiverse
# deb-src ${mirror_url} ${UBUNTU_CODENAME}-updates main restricted universe multiverse
# deb-src ${mirror_url} ${UBUNTU_CODENAME}-backports main restricted universe multiverse
# deb-src ${mirror_url} ${UBUNTU_CODENAME}-security main restricted universe multiverse
EOF

  echo "Ubuntu 镜像源配置完成!"
  echo "是否立即执行 apt update 更新软件包列表? [Y/n]:"
  read -p "" do_update
  if [[ ! "$do_update" =~ ^[Nn] ]]; then
    apt update
  else
    echo "请稍后手动执行: apt update"
  fi

# ==================== CentOS 配置 ====================
elif [ "$TARGET_OS" = "CentOS" ]; then
  # 检测 CentOS 主版本号
  if [ -f /etc/centos-release ]; then
    centos_ver=$(rpm -q --qf "%{VERSION}" centos-release)
    CENTOS_MAJOR=$(echo "$centos_ver" | cut -d. -f1)
  elif [ -f /etc/os-release ]; then
    . /etc/os-release
    CENTOS_MAJOR=$(echo "$VERSION_ID" | cut -d. -f1)
  fi

  if [ -z "$CENTOS_MAJOR" ]; then
    echo "无法自动检测 CentOS 主版本号,请手动输入 (例如 7, 8, 9):"
    read -p "版本号: " CENTOS_MAJOR
  else
    echo "检测到 CentOS 主版本号: $CENTOS_MAJOR"
    read -p "是否使用该版本? [Y/n]: " confirm
    if [[ "$confirm" =~ ^[Nn] ]]; then
      read -p "请输入正确的版本号: " CENTOS_MAJOR
    fi
  fi

  # 对于 CentOS 8 及以上,可能需要处理 vault 仓库(尤其是 EOL 版本)
  if [ "$CENTOS_MAJOR" -ge 8 ]; then
    echo "注意: CentOS $CENTOS_MAJOR 可能已停止维护,建议使用 vault 镜像。"
    read -p "是否使用 vault 镜像 (针对旧版本)? [y/N]: " use_vault
    if [[ "$use_vault" =~ ^[Yy] ]]; then
      mirror_url="${mirror_url}vault/"
    fi
  fi

  # 设置 repo 文件路径
  REPO_FILE="/etc/yum.repos.d/CentOS-Base.repo"
  BACKUP_FILE="${REPO_FILE}.backup.$(date +%Y%m%d%H%M%S)"

  # 备份原文件
  if [ -f "$REPO_FILE" ]; then
    cp "$REPO_FILE" "$BACKUP_FILE"
    echo "已备份原始 repo 文件到: $BACKUP_FILE"
  else
    echo "未找到 $REPO_FILE,将创建新文件。"
  fi

  # 生成新的 CentOS-Base.repo
  cat > "$REPO_FILE" <<EOF
# 由脚本自动生成,镜像源: $mirror_name
# 备份文件: $BACKUP_FILE

[base]
name=CentOS-\$releasever - Base
baseurl=${mirror_url}\$releasever/os/\$basearch/
gpgcheck=1
gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-\$releasever
enabled=1

[updates]
name=CentOS-\$releasever - Updates
baseurl=${mirror_url}\$releasever/updates/\$basearch/
gpgcheck=1
gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-\$releasever
enabled=1

[extras]
name=CentOS-\$releasever - Extras
baseurl=${mirror_url}\$releasever/extras/\$basearch/
gpgcheck=1
gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-\$releasever
enabled=1

# 可选: epel 仓库 (如需要请取消注释)
# [epel]
# name=Extra Packages for Enterprise Linux \${releasever} - \${basearch}
# baseurl=https://mirrors.aliyun.com/epel/\${releasever}/\${basearch}
# gpgcheck=1
# gpgkey=https://mirrors.aliyun.com/epel/RPM-GPG-KEY-EPEL-\${releasever}
# enabled=0
EOF

  # 对于 CentOS 8 以上,如果使用 vault,可能需要修改 gpgkey 路径
  if [[ "$use_vault" =~ ^[Yy] ]]; then
    sed -i 's|http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-\$releasever|https://www.centos.org/keys/RPM-GPG-KEY-CentOS-Official|g' "$REPO_FILE"
  fi

  echo "CentOS 镜像源配置完成!"
  echo "是否立即执行 yum makecache 更新缓存? [Y/n]:"
  read -p "" do_update
  if [[ ! "$do_update" =~ ^[Nn] ]]; then
    yum makecache
  else
    echo "请稍后手动执行: yum makecache"
  fi
fi

echo "========================================="
echo "镜像源配置脚本执行完毕。"
echo "如需恢复原始配置,请使用备份文件: $BACKUP_FILE"

3️⃣ 赋予执行权限并运行

chmod +x configure_mirror.sh
sudo ./configure_mirror.sh

🧠 脚本核心逻辑解析

步骤 实现技术点
权限检测 if [ "$EUID" -ne 0 ] 确保 root 执行
系统识别 读取 /etc/os-release 的 ID 字段,自动提示当前系统
交互菜单 使用 select 循环显示镜像源列表,支持自定义 URL
版本自动获取 Ubuntu 通过 VERSION_CODENAME 获取;CentOS 通过 rpm -q centos-release 或 VERSION_ID 获取主版本号
备份机制 cp file file.backup.$(date +%Y%m%d%H%M%S) 带时间戳,避免覆盖
配置文件生成 使用 cat > file <<EOF ... EOF 多行重定向,按官方标准写入源配置
CentOS vault 处理 对 EOL 版本(8+)询问是否使用 vault,并自动修改 gpgkey 地址
可选更新 执行完配置后询问是否立即 apt update 或 yum makecache,人性化

💡 常见问题

Q1:脚本检测到的系统版本不对怎么办?
→ 脚本会询问“是否使用该代号/版本”,选择 n 然后手动输入正确的即可。

Q2:CentOS 8 已经 EOL,脚本能处理吗?
→ 可以。当检测到主版本号 ≥8 时,会询问是否使用 vault 镜像,选 y 后自动将 baseurl 指向 vault 目录,并更换 gpgkey 为官方稳定地址。

Q3:我用的不是纯 CentOS,而是 Rocky Linux / AlmaLinux,能用吗?
→ 可以。脚本检测时会将 rocky|almalinux 识别为 CentOS 类型,生成的 repo 文件同样适用(可能需要微调 gpgkey,但基础仓库可正常工作)。

Q4:运行后怎么恢复原来的源?
→ 脚本执行后会显示备份文件路径,例如 /etc/apt/sources.list.backup.20250612143022。直接复制回来即可:
cp /path/to/backup /etc/apt/sources.list

Q5:脚本支持 Debian 吗?
→ 目前仅内置 Ubuntu 和 CentOS,但你可以选择“自定义URL”并手动输入 Debian 镜像地址,然后手动生成 sources.list。如需自动化,可以简单修改脚本扩展。


🎯 拓展建议

  1. 增加 EPEL 仓库开关:脚本中已注释 EPEL 示例,可增加询问是否启用并自动配置。

  2. 支持更多发行版:Debian、Fedora、OpenSUSE 等,只需添加对应的仓库模板和版本检测。

  3. 自动测试源速度:集成 apt-get update --print-uris 或 curl 测速,自动选择最快的镜像。

  4. 备份清理功能:定期清理超过 30 天的备份文件,避免 /etc 目录膨胀。


📢 结语

这个脚本在我管理的十几台国内服务器和开发机上经过反复测试,从未出现配置错误。它把换源这个高频、低技术含量但容易手误的操作,变成了“选数字 + 按回车”的愉快体验。

如果你也受够了每次装系统都要手动改源,赶紧下载这个脚本,收藏起来,以后换源不求人!

🚀 脚本完全开源,欢迎按需修改。如果你发现 bug 或有更好的镜像源,评论区告诉我!

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐