Skip to content
shell
#!/bin/bash

################################################################################
# Linux 系统初始化脚本 v1.1
# 功能: 镜像源切换 | 基础工具安装 | 系统优化配置
# 支持: Ubuntu/Debian, CentOS/RHEL, Rocky Linux, AlmaLinux
# 作者: Gettler
# 使用: sudo ./init_system.sh [--auto] [--mirror=aliyun] [--non-interactive]
################################################################################

set -euo pipefail

# 颜色定义 - 用于终端彩色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
PURPLE='\033[0;35m'
NC='\033[0m'  # No Color

# 日志文件定义
LOG_FILE="/var/log/system-init-$(date +%Y%m%d-%H%M%S).log"

# 输出函数定义
print_info() {
    echo -e "${BLUE}[INFO]${NC} $1" | tee -a "$LOG_FILE"
}

print_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1" | tee -a "$LOG_FILE"
}

print_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1" | tee -a "$LOG_FILE"
}

print_error() {
    echo -e "${RED}[ERROR]${NC} $1" | tee -a "$LOG_FILE"
    echo "详细日志请查看: $LOG_FILE" >&2
}

# 错误处理函数
error_exit() {
    print_error "$1"
    exit 1
}

# 检查命令是否存在
check_command() {
    if ! command -v "$1" &> /dev/null; then
        print_warning "命令 $1 未找到,正在安装..."
        case $OS in
            ubuntu|debian)
                sudo apt-get update && sudo apt-get install -y "$1" || {
                    print_error "安装 $1 失败"
                    return 1
                }
                ;;
            centos|rhel|rocky|almalinux)
                sudo yum install -y "$1" || {
                    print_error "安装 $1 失败"
                    return 1
                }
                ;;
        esac
    fi
    return 0
}

# 脚本横幅显示
print_banner() {
    clear
    echo -e "${PURPLE}"
    echo "=================================================="
    echo "       Linux 系统初始化脚本 v1.1"
    echo "=================================================="
    echo "功能: 镜像源切换 | 基础工具安装 | 系统优化配置"
    echo "支持: Ubuntu/Debian, CentOS/RHEL, Rocky, AlmaLinux"
    echo "=================================================="
    echo -e "${NC}"
    echo "日志文件: $LOG_FILE" | tee -a "$LOG_FILE"
    echo "开始时间: $(date)" | tee -a "$LOG_FILE"
    echo "==================================================" | tee -a "$LOG_FILE"
}

# 检查脚本运行权限
check_permissions() {
    if [[ $EUID -ne 0 ]] && ! sudo -n true 2>/dev/null; then
        error_exit "此脚本需要 root 权限或 sudo 权限\n请使用: sudo $0"
    fi
    print_success "权限检查通过"
}

# 检测操作系统类型和版本
detect_os() {
    print_info "正在检测操作系统..."

    # 检查 /etc/os-release 文件是否存在
    if [[ ! -f /etc/os-release ]]; then
        error_exit "无法检测操作系统: /etc/os-release 文件不存在"
    fi

    # 加载操作系统信息
    . /etc/os-release

    # 设置全局变量
    OS="$ID"
    OS_NAME="$NAME"
    OS_VERSION="${VERSION_ID:-unknown}"

    # 显示检测结果
    print_success "操作系统: $OS_NAME $OS_VERSION"

    # 检测网络环境
    detect_network
}

# 检测网络环境(国内/国际)
detect_network() {
    print_info "正在检测网络环境..."

    # 测试多个网站,增加检测准确性
    local test_sites=(
        "www.baidu.com"
        "www.google.com"
        "github.com"
        "mirrors.aliyun.com"
    )

    local china_count=0
    local international_count=0

    for site in "${test_sites[@]}"; do
        if timeout 3 curl -s --head "$site" > /dev/null 2>&1; then
            case "$site" in
                *baidu.com*|*aliyun.com*)
                    ((china_count++))
                    ;;
                *google.com*|*github.com*)
                    ((international_count++))
                    ;;
            esac
        fi
    done

    # 根据检测结果判断网络环境
    if [[ $china_count -gt $international_count ]]; then
        NETWORK_ENV="china"
        print_info "检测到国内网络环境,建议使用国内镜像源"
    elif [[ $international_count -gt 0 ]]; then
        NETWORK_ENV="international"
        print_info "检测到国际网络环境"
    else
        NETWORK_ENV="unknown"
        print_warning "网络环境检测失败,请检查网络连接"
    fi
}

# 备份原始软件源
backup_sources() {
    print_info "正在备份原始软件源..."

    local backup_dir="/etc/apt/backup-$(date +%Y%m%d)"

    case $OS in
        ubuntu|debian)
            # 创建备份目录
            sudo mkdir -p "$backup_dir"

            # 备份 sources.list
            if [[ -f /etc/apt/sources.list ]]; then
                sudo cp /etc/apt/sources.list "$backup_dir/sources.list.bak"
                print_success "已备份到 $backup_dir/sources.list.bak"
            fi

            # 备份 sources.list.d 目录
            if [[ -d /etc/apt/sources.list.d ]]; then
                sudo cp -r /etc/apt/sources.list.d "$backup_dir/"
                print_success "已备份 sources.list.d 目录"
            fi
            ;;

        centos|rhel|rocky|almalinux)
            backup_dir="/etc/yum.repos.d/backup-$(date +%Y%m%d)"
            sudo mkdir -p "$backup_dir"

            # 备份所有 .repo 文件
            if ls /etc/yum.repos.d/*.repo &> /dev/null; then
                sudo cp /etc/yum.repos.d/*.repo "$backup_dir/"
                print_success "已备份到 $backup_dir/"
            else
                print_warning "未找到 .repo 文件,跳过备份"
            fi
            ;;

        *)
            print_warning "不支持的操作系统,跳过备份"
            ;;
    esac
}

# 配置 Ubuntu/Debian 镜像源
configure_ubuntu_mirrors() {
    print_info "正在配置 Ubuntu/Debian 镜像源..."

    # 获取 Ubuntu 版本代号
    local ubuntu_codename
    if command -v lsb_release &> /dev/null; then
        ubuntu_codename=$(lsb_release -cs)
    else
        # 根据版本号推测代号
        case "$OS_VERSION" in
            "22.04") ubuntu_codename="jammy" ;;
            "20.04") ubuntu_codename="focal" ;;
            "18.04") ubuntu_codename="bionic" ;;
            "16.04") ubuntu_codename="xenial" ;;
            *) ubuntu_codename="jammy" ;; # 默认使用最新 LTS
        esac
    fi

    # 如果指定了镜像源参数,直接使用
    local mirror_url=""
    local mirror_name=""

    if [[ -n "${MIRROR_ARG:-}" ]]; then
        case "${MIRROR_ARG}" in
            aliyun)
                mirror_url="http://mirrors.aliyun.com"
                mirror_name="阿里云"
                ;;
            tsinghua)
                mirror_url="https://mirrors.tuna.tsinghua.edu.cn"
                mirror_name="清华大学"
                ;;
            ustc)
                mirror_url="https://mirrors.ustc.edu.cn"
                mirror_name="中国科技大学"
                ;;
            huawei)
                mirror_url="https://repo.huaweicloud.com"
                mirror_name="华为云"
                ;;
            nju)
                mirror_url="https://mirrors.nju.edu.cn"
                mirror_name="南京大学"
                ;;
            *)
                print_warning "未知的镜像源参数,使用交互式选择"
                MIRROR_ARG=""
                ;;
        esac
    fi

    # 如果没有通过参数指定镜像源,则进行交互式选择
    if [[ -z "$mirror_url" ]]; then
        echo ""
        echo "请选择镜像源:"
        echo "1) 阿里云 (推荐国内用户)"
        echo "2) 清华大学"
        echo "3) 中国科技大学"
        echo "4) 华为云"
        echo "5) 南京大学"
        echo "6) 官方源 (推荐国际用户)"
        echo ""

        read -rp "请选择 [1-6, 默认: 1]: " mirror_choice
        mirror_choice=${mirror_choice:-1}

        case $mirror_choice in
            1)
                mirror_url="http://mirrors.aliyun.com"
                mirror_name="阿里云"
                ;;
            2)
                mirror_url="https://mirrors.tuna.tsinghua.edu.cn"
                mirror_name="清华大学"
                ;;
            3)
                mirror_url="https://mirrors.ustc.edu.cn"
                mirror_name="中国科技大学"
                ;;
            4)
                mirror_url="https://repo.huaweicloud.com"
                mirror_name="华为云"
                ;;
            5)
                mirror_url="https://mirrors.nju.edu.cn"
                mirror_name="南京大学"
                ;;
            6)
                print_info "使用官方源"
                mirror_url="http://archive.ubuntu.com"
                mirror_name="官方源"
                ;;
            *)
                print_warning "无效选择,使用阿里云镜像"
                mirror_url="http://mirrors.aliyun.com"
                mirror_name="阿里云"
                ;;
        esac
    fi

    print_info "正在配置 $mirror_name 镜像源..."

    # 生成新的 sources.list
    if [[ "$mirror_url" == "http://archive.ubuntu.com" ]]; then
        # 官方源配置
        sudo tee /etc/apt/sources.list > /dev/null <<EOF
# Ubuntu 官方源
deb http://archive.ubuntu.com/ubuntu/ $ubuntu_codename main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu/ $ubuntu_codename-updates main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu/ $ubuntu_codename-backports main restricted universe multiverse
deb http://security.ubuntu.com/ubuntu/ $ubuntu_codename-security main restricted universe multiverse
EOF
    else
        # 国内镜像源配置
        sudo tee /etc/apt/sources.list > /dev/null <<EOF
# $mirror_name 镜像源
deb $mirror_url/ubuntu/ $ubuntu_codename main restricted universe multiverse
deb $mirror_url/ubuntu/ $ubuntu_codename-updates main restricted universe multiverse
deb $mirror_url/ubuntu/ $ubuntu_codename-backports main restricted universe multiverse
deb $mirror_url/ubuntu/ $ubuntu_codename-security main restricted universe multiverse

# 源码仓库
# deb-src $mirror_url/ubuntu/ $ubuntu_codename main restricted universe multiverse
# deb-src $mirror_url/ubuntu/ $ubuntu_codename-updates main restricted universe multiverse
# deb-src $mirror_url/ubuntu/ $ubuntu_codename-backports main restricted universe multiverse
# deb-src $mirror_url/ubuntu/ $ubuntu_codename-security main restricted universe multiverse
EOF
    fi

    print_success "$mirror_name 镜像源配置完成"

    # 更新软件包索引
    print_info "正在更新软件包索引..."
    if sudo apt-get update; then
        print_success "软件包索引更新完成"
    else
        print_warning "软件包索引更新失败,请检查网络连接"
        return 1
    fi

    return 0
}

# 配置 CentOS/RHEL/Rocky/AlmaLinux 镜像源
configure_centos_mirrors() {
    print_info "正在配置 CentOS/RHEL/Rocky/AlmaLinux 镜像源..."

    local mirror_url=""
    local mirror_name=""

    # 如果指定了镜像源参数,直接使用
    if [[ -n "${MIRROR_ARG:-}" ]]; then
        case "${MIRROR_ARG}" in
            aliyun)
                mirror_url="https://mirrors.aliyun.com"
                mirror_name="阿里云"
                ;;
            tsinghua)
                mirror_url="https://mirrors.tuna.tsinghua.edu.cn"
                mirror_name="清华大学"
                ;;
            ustc)
                mirror_url="https://mirrors.ustc.edu.cn"
                mirror_name="中国科技大学"
                ;;
            huawei)
                mirror_url="https://repo.huaweicloud.com"
                mirror_name="华为云"
                ;;
            *)
                print_warning "未知的镜像源参数,使用交互式选择"
                MIRROR_ARG=""
                ;;
        esac
    fi

    # 交互式选择镜像源
    if [[ -z "$mirror_url" ]]; then
        echo ""
        echo "请选择镜像源:"
        echo "1) 阿里云 (推荐)"
        echo "2) 清华大学"
        echo "3) 中国科技大学"
        echo "4) 华为云"
        echo "5) 官方源"
        echo ""

        read -rp "请选择 [1-5, 默认: 1]: " mirror_choice
        mirror_choice=${mirror_choice:-1}

        case $mirror_choice in
            1)
                mirror_url="https://mirrors.aliyun.com"
                mirror_name="阿里云"
                ;;
            2)
                mirror_url="https://mirrors.tuna.tsinghua.edu.cn"
                mirror_name="清华大学"
                ;;
            3)
                mirror_url="https://mirrors.ustc.edu.cn"
                mirror_name="中国科技大学"
                ;;
            4)
                mirror_url="https://repo.huaweicloud.com"
                mirror_name="华为云"
                ;;
            5)
                print_info "使用官方源"
                mirror_name="官方源"
                ;;
            *)
                print_warning "无效选择,使用阿里云镜像"
                mirror_url="https://mirrors.aliyun.com"
                mirror_name="阿里云"
                ;;
        esac
    fi

    print_info "正在配置 $mirror_name 镜像源..."

    # 根据不同的发行版和版本进行配置
    case $OS in
        centos)
            configure_centos_mirror "$mirror_url" "$mirror_name"
            ;;
        rocky|almalinux)
            configure_rocky_mirror "$mirror_url" "$mirror_name"
            ;;
        rhel)
            print_warning "RHEL 系统需要订阅,建议使用官方源或配置本地源"
            ;;
    esac

    # 清理缓存并更新
    print_info "清理缓存并更新..."
    sudo yum clean all
    sudo yum makecache

    print_success "镜像源配置完成"
}

# 配置 CentOS 镜像源
configure_centos_mirror() {
    local mirror_url="$1"
    local mirror_name="$2"

    # 禁用所有官方仓库
    sudo sed -i 's/enabled=1/enabled=0/g' /etc/yum.repos.d/CentOS-*.repo

    # 根据 CentOS 版本配置镜像源
    case $OS_VERSION in
        7)
            sudo tee /etc/yum.repos.d/centos7.repo > /dev/null <<EOF
[base]
name=CentOS-\$releasever - Base
baseurl=$mirror_url/centos/\$releasever/os/\$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
enabled=1

[updates]
name=CentOS-\$releasever - Updates
baseurl=$mirror_url/centos/\$releasever/updates/\$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
enabled=1

[extras]
name=CentOS-\$releasever - Extras
baseurl=$mirror_url/centos/\$releasever/extras/\$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
enabled=1

[centosplus]
name=CentOS-\$releasever - Plus
baseurl=$mirror_url/centos/\$releasever/centosplus/\$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
enabled=0
EOF
            ;;

        8|8.*)
            sudo tee /etc/yum.repos.d/centos8.repo > /dev/null <<EOF
[BaseOS]
name=CentOS-\$releasever - Base
baseurl=$mirror_url/centos/\$releasever/BaseOS/\$basearch/os/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
enabled=1

[AppStream]
name=CentOS-\$releasever - AppStream
baseurl=$mirror_url/centos/\$releasever/AppStream/\$basearch/os/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
enabled=1

[extras]
name=CentOS-\$releasever - Extras
baseurl=$mirror_url/centos/\$releasever/extras/\$basearch/os/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
enabled=1

[PowerTools]
name=CentOS-\$releasever - PowerTools
baseurl=$mirror_url/centos/\$releasever/PowerTools/\$basearch/os/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
enabled=0
EOF
            ;;

        *)
            print_warning "CentOS $OS_VERSION 版本可能不受完全支持"
            ;;
    esac
}

# 配置 Rocky Linux 镜像源
configure_rocky_mirror() {
    local mirror_url="$1"
    local mirror_name="$2"

    # Rocky Linux 9+ 使用新的仓库结构
    if [[ $OS_VERSION == 9* ]]; then
        sudo tee /etc/yum.repos.d/rocky.repo > /dev/null <<EOF
[baseos]
name=Rocky Linux \$releasever - BaseOS
baseurl=$mirror_url/rocky/\$releasever/BaseOS/\$basearch/os/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-9

[appstream]
name=Rocky Linux \$releasever - AppStream
baseurl=$mirror_url/rocky/\$releasever/AppStream/\$basearch/os/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-9

[extras]
name=Rocky Linux \$releasever - Extras
baseurl=$mirror_url/rocky/\$releasever/extras/\$basearch/os/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-9
EOF
    else
        print_warning "Rocky Linux $OS_VERSION 版本使用默认配置"
    fi
}

# 安装基础工具
install_basic_tools() {
    print_info "正在安装基础工具..."

    # 工具列表定义
    local ubuntu_tools=(
        curl wget git
        vim nano
        htop screen tmux
        net-tools iputils-ping dnsutils
        unzip zip tar gzip bzip2
        build-essential
        software-properties-common
        apt-transport-https ca-certificates
        gnupg lsb-release
        tree ncdu
        jq
        python3 python3-pip
    )

    local centos_tools=(
        curl wget git
        vim nano
        htop screen tmux
        net-tools iproute
        unzip zip tar gzip bzip2
        gcc gcc-c++ make
        epel-release
        tree ncdu
        jq
        python3 python3-pip
    )

    # 询问用户是否自定义工具列表
    if [[ -z "${NON_INTERACTIVE:-}" ]]; then
        echo ""
        echo "默认安装以下工具:"

        case $OS in
            ubuntu|debian)
                printf '%s\n' "${ubuntu_tools[@]}"
                ;;
            centos|rhel|rocky|almalinux)
                printf '%s\n' "${centos_tools[@]}"
                ;;
        esac

        echo ""
        read -rp "是否安装这些工具? [Y/n]: " install_tools
        install_tools=${install_tools:-Y}

        if [[ ! $install_tools =~ ^[Yy]$ ]]; then
            print_info "跳过基础工具安装"
            return
        fi
    fi

    # 安装工具
    case $OS in
        ubuntu|debian)
            print_info "更新软件包列表..."
            sudo apt-get update

            print_info "安装 Ubuntu/Debian 工具包..."
            sudo apt-get install -y "${ubuntu_tools[@]}" || {
                print_warning "部分工具安装失败,继续执行..."
            }
            ;;

        centos|rhel|rocky|almalinux)
            print_info "安装 EPEL 仓库..."
            sudo yum install -y epel-release || true

            print_info "安装 CentOS/RHEL 工具包..."
            sudo yum install -y "${centos_tools[@]}" || {
                print_warning "部分工具安装失败,继续执行..."
            }
            ;;
    esac

    print_success "基础工具安装完成"
}

# 配置 SSH 服务
configure_ssh() {
    print_info "正在配置 SSH 服务..."

    # 检查是否安装 SSH 服务
    if ! systemctl is-active sshd &> /dev/null && ! systemctl is-active ssh &> /dev/null; then
        print_warning "SSH 服务未安装,正在安装..."
        case $OS in
            ubuntu|debian)
                sudo apt-get install -y openssh-server
                ;;
            centos|rhel|rocky|almalinux)
                sudo yum install -y openssh-server
                ;;
        esac
    fi

    # 询问是否配置 SSH
    if [[ -z "${NON_INTERACTIVE:-}" ]]; then
        read -rp "是否优化 SSH 配置? [y/N]: " config_ssh
        config_ssh=${config_ssh:-N}

        if [[ ! $config_ssh =~ ^[Yy]$ ]]; then
            print_info "跳过 SSH 配置"
            return
        fi
    fi

    # 备份 SSH 配置
    local ssh_config_backup="/etc/ssh/sshd_config.backup-$(date +%Y%m%d)"
    sudo cp /etc/ssh/sshd_config "$ssh_config_backup"
    print_success "SSH 配置已备份到 $ssh_config_backup"

    # SSH 优化配置参数
    local ssh_config_changes=(
        "# 优化 SSH 配置 - 修改于 $(date)"
        "UseDNS no"
        "GSSAPIAuthentication no"
        "ClientAliveInterval 60"
        "ClientAliveCountMax 3"
        "MaxAuthTries 3"
        "LoginGraceTime 60"
        "PermitRootLogin prohibit-password"
        "PasswordAuthentication yes"
        "PubkeyAuthentication yes"
        "AllowTcpForwarding yes"
        "X11Forwarding no"
        "PrintMotd no"
        "PrintLastLog yes"
    )

    # 应用 SSH 配置
    print_info "应用 SSH 优化配置..."

    # 删除旧配置并添加新配置
    for config_line in "${ssh_config_changes[@]}"; do
        if [[ $config_line =~ ^[^#] ]]; then
            local config_key=$(echo "$config_line" | awk '{print $1}')
            sudo sed -i "/^$config_key/d" /etc/ssh/sshd_config
        fi
    done

    # 添加新配置
    for config_line in "${ssh_config_changes[@]}"; do
        echo "$config_line" | sudo tee -a /etc/ssh/sshd_config > /dev/null
    done

    # 重启 SSH 服务
    print_info "重启 SSH 服务..."
    if command -v systemctl &> /dev/null; then
        sudo systemctl daemon-reload
        sudo systemctl restart sshd 2>/dev/null || sudo systemctl restart ssh 2>/dev/null
        sudo systemctl enable sshd 2>/dev/null || sudo systemctl enable ssh 2>/dev/null
    else
        sudo service sshd restart 2>/dev/null || sudo service ssh restart 2>/dev/null
    fi

    print_success  "SSH 配置优化完成"
}

# 配置时区
configure_timezone() {
    print_info "正在配置时区..."

    local current_tz=""

    # 获取当前时区
    if command -v timedatectl &> /dev/null; then
        current_tz=$(timedatectl | grep "Time zone" | awk '{print $3}')
    fi

    print_info "当前时区: ${current_tz:-未知}"

    # 询问是否设置时区
    if [[ -z "${NON_INTERACTIVE:-}" ]]; then
        read -rp "是否设置为中国时区 (Asia/Shanghai)? [Y/n]: " set_tz
        set_tz=${set_tz:-Y}
    else
        set_tz="Y"
    fi

    if [[ $set_tz =~ ^[Yy]$ ]]; then
        # 尝试使用 timedatectl
        if command -v timedatectl &> /dev/null; then
            sudo timedatectl set-timezone Asia/Shanghai
        else
            # 备选方案:直接链接时区文件
            sudo ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
            if [[ -f /etc/redhat-release ]]; then
                echo "ZONE=\"Asia/Shanghai\"" | sudo tee /etc/sysconfig/clock > /dev/null
            fi
        fi

        # 同步硬件时钟
        sudo hwclock --systohc 2>/dev/null || true

        print_success "时区已设置为 Asia/Shanghai"
    fi
}

# 配置语言环境
configure_locale() {
    print_info "正在配置语言环境..."

    # 询问是否配置中文语言环境
    if [[ -z "${NON_INTERACTIVE:-}" ]]; then
        read -rp "是否配置中文语言环境? [y/N]: " set_locale
        set_locale=${set_locale:-N}

        if [[ ! $set_locale =~ ^[Yy]$ ]]; then
            print_info "跳过语言环境配置"
            return
        fi
    fi

    case $OS in
        ubuntu|debian)
            # 安装中文语言包
            sudo apt-get install -y language-pack-zh-hans

            # 生成语言环境
            sudo locale-gen zh_CN.UTF-8
            sudo locale-gen zh_CN.GBK
            sudo locale-gen zh_CN.GB2312

            # 设置系统语言环境
            sudo update-locale LANG=zh_CN.UTF-8 LC_ALL=zh_CN.UTF-8
            ;;

        centos|rhel|rocky|almalinux)
            # 安装中文语言包
            sudo yum install -y glibc-langpack-zh

            # 设置语言环境
            local lang_conf="/etc/locale.conf"
            if [[ -f "$lang_conf" ]]; then
                sudo sed -i 's/^LANG=.*/LANG="zh_CN.UTF-8"/' "$lang_conf"
            else
                echo 'LANG="zh_CN.UTF-8"' | sudo tee "$lang_conf" > /dev/null
            fi
            ;;
    esac

    # 设置临时环境变量
    export LANG=zh_CN.UTF-8
    export LC_ALL=zh_CN.UTF-8

    print_success "中文语言环境配置完成"
}

# 系统优化配置
optimize_system() {
    print_info "正在应用系统优化配置..."

    # 询问是否进行系统优化
    if [[ -z "${NON_INTERACTIVE:-}" ]]; then
        read -rp "是否应用系统优化配置? [Y/n]: " do_optimize
        do_optimize=${do_optimize:-Y}

        if [[ ! $do_optimize =~ ^[Yy]$ ]]; then
            print_info "跳过系统优化"
            return
        fi
    fi

    # 1. 优化文件描述符限制
    optimize_file_descriptors

    # 2. 优化内核参数
    optimize_kernel_params

    # 3. 优化系统服务
    optimize_services

    # 4. 优化交换分区
    optimize_swap

    print_success "系统优化配置完成"
}

# 优化文件描述符限制
optimize_file_descriptors() {
    print_info "优化文件描述符限制..."

    local limits_conf="/etc/security/limits.conf"

    # 备份原配置
    sudo cp "$limits_conf" "${limits_conf}.backup-$(date +%Y%m%d)"

    # 设置文件描述符限制
    if ! grep -q "^\* soft nofile" "$limits_conf"; then
        echo "* soft nofile 65535" | sudo tee -a "$limits_conf" > /dev/null
        echo "* hard nofile 65535" | sudo tee -a "$limits_conf" > /dev/null
        echo "root soft nofile 65535" | sudo tee -a "$limits_conf" > /dev/null
        echo "root hard nofile 65535" | sudo tee -a "$limits_conf" > /dev/null
        print_success "文件描述符限制已优化"
    else
        print_info "文件描述符限制已经配置"
    fi

    # 对于 systemd 系统
    if [[ -d /etc/systemd/system ]]; then
        local systemd_conf="/etc/systemd/system.conf"
        sudo sed -i 's/^#DefaultLimitNOFILE=.*/DefaultLimitNOFILE=65535/' "$systemd_conf"
        sudo sed -i 's/^#DefaultLimitNPROC=.*/DefaultLimitNPROC=65535/' "$systemd_conf"
    fi
}

# 优化内核参数
optimize_kernel_params() {
    print_info "优化内核参数..."

    local sysctl_conf="/etc/sysctl.d/99-custom.conf"

    # 创建优化配置文件
    sudo tee "$sysctl_conf" > /dev/null <<'EOF'
# ========================
# 系统内核优化配置
# 生成时间: $(date)
# ========================

# 网络优化
# 最大连接数
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 65535

# 缓冲区大小
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216

# TCP 优化
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_syn_retries = 2
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_max_tw_buckets = 2000000
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_intvl = 30

# 连接跟踪
net.netfilter.nf_conntrack_max = 655350
net.netfilter.nf_conntrack_tcp_timeout_established = 1200

# 文件系统优化
fs.file-max = 6553500
fs.inotify.max_user_watches = 524288
fs.inotify.max_user_instances = 256

# 内存优化
vm.swappiness = 10
vm.vfs_cache_pressure = 50
vm.dirty_ratio = 10
vm.dirty_background_ratio = 5
vm.overcommit_memory = 1

# IPv6 配置 (如果不需要可以禁用)
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1

# 安全设置
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.icmp_ignore_bogus_error_responses = 1
EOF

    # 重新加载 sysctl 配置
    sudo sysctl -p "$sysctl_conf" > /dev/null 2>&1 || {
        print_warning "部分内核参数优化失败,可能需要在重启后生效"
    }

    print_success "内核参数优化完成"
}

# 优化系统服务
optimize_services() {
    print_info "优化系统服务..."

    # 禁用不必要的服务(根据实际情况调整)
    local services_to_disable=(
        "postfix"    # 邮件服务,如果不是邮件服务器
        "avahi-daemon"  # mDNS 服务
    )

    for service in "${services_to_disable[@]}"; do
        if systemctl is-enabled "$service" &> /dev/null; then
            sudo systemctl disable "$service" 2>/dev/null || true
            sudo systemctl stop "$service" 2>/dev/null || true
            print_info "已禁用服务: $service"
        fi
    done
}

# 优化交换分区
optimize_swap() {
    print_info "优化交换分区..."

    # 检查交换分区是否存在
    if [[ $(swapon --show | wc -l) -eq 0 ]]; then
        print_warning "未找到交换分区,如需创建请运行: sudo fallocate -l 2G /swapfile && sudo chmod 600 /swapfile && sudo mkswap /swapfile && sudo swapon /swapfile"
        return
    fi

    # 调整 swappiness 值(如果已经在内核参数中设置过,这里不会重复设置)
    local current_swappiness=$(cat /proc/sys/vm/swappiness 2>/dev/null || echo "60")
    print_info "当前 swappiness 值: $current_swappiness"
}

# 清理系统
clean_system() {
    print_info "正在清理系统..."

    # 询问是否清理系统
    if [[ -z "${NON_INTERACTIVE:-}" ]]; then
        read -rp "是否清理系统缓存和无用包? [Y/n]: " do_clean
        do_clean=${do_clean:-Y}

        if [[ ! $do_clean =~ ^[Yy]$ ]]; then
            print_info "跳过系统清理"
            return
        fi
    fi

    case $OS in
        ubuntu|debian)
            print_info "清理 APT 缓存..."
            sudo apt-get autoremove -y
            sudo apt-get autoclean -y
            sudo apt-get clean

            # 清理旧内核
            sudo apt-get purge -y $(dpkg -l | awk '/^ii linux-image-*/ && $2 !~ /'$(uname -r)'/ {print $2}') 2>/dev/null || true

            # 清理日志文件(保留最近7天)
            sudo find /var/log -type f -name "*.log" -mtime +7 -delete 2>/dev/null || true
            ;;

        centos|rhel|rocky|almalinux)
            print_info "清理 YUM 缓存..."
            sudo yum autoremove -y
            sudo yum clean all

            # 清理旧内核(保留最近2个)
            sudo package-cleanup --oldkernels --count=2 -y 2>/dev/null || true

            # 清理日志文件
            sudo journalctl --vacuum-time=7d 2>/dev/null || true
            ;;
    esac

    # 清理临时文件
    print_info "清理临时文件..."
    sudo rm -rf /tmp/* 2>/dev/null || true
    sudo rm -rf /var/tmp/* 2>/dev/null || true

    print_success "系统清理完成"
}

# 显示系统信息
show_system_info() {
    echo ""
    print_success "==================== 系统信息 ===================="
    echo ""

    # 操作系统信息
    if [[ -f /etc/os-release ]]; then
        echo "操作系统: $(grep PRETTY_NAME /etc/os-release | cut -d'"' -f2)"
    fi

    # 内核信息
    echo "内核版本: $(uname -r)"
    echo "系统架构: $(uname -m)"

    # CPU 信息
    if command -v nproc &> /dev/null; then
        echo "CPU 核心: $(nproc)"
    fi

    # 内存信息
    if command -v free &> /dev/null; then
        echo "内存大小: $(free -h | awk '/^Mem:/ {print $2}')"
        echo "可用内存: $(free -h | awk '/^Mem:/ {print $7}')"
    fi

    # 磁盘信息
    if command -v df &> /dev/null; then
        echo "根目录空间: $(df -h / | awk 'NR==2 {print $2 " 已用: " $3 " (" $5 ")"}')"
    fi

    # 系统负载
    if [[ -f /proc/loadavg ]]; then
        load=$(cat /proc/loadavg)
        echo "系统负载: ${load:0:16}"
    fi

    # 运行时间
    if command -v uptime &> /dev/null; then
        echo "运行时间: $(uptime -p | sed 's/up //')"
    fi

    # 用户信息
    echo "当前用户: $(whoami)"
    echo "主机名称: $(hostname)"

    # IP 地址信息
    if command -v ip &> /dev/null; then
        echo "IP 地址: $(ip route get 1 | awk '{print $7; exit}')"
    elif command -v hostname &> /dev/null; then
        echo "主机名: $(hostname -I 2>/dev/null | awk '{print $1}')"
    fi

    # 时区信息
    if command -v timedatectl &> /dev/null; then
        echo "时区设置: $(timedatectl | grep "Time zone" | awk '{print $3}')"
        echo "NTP 同步: $(timedatectl | grep "NTP synchronized" | awk '{print $3}')"
    fi

    echo ""
    print_success "=================================================="
    echo ""
}

# 显示主菜单
show_menu() {
    echo ""
    echo "请选择要执行的操作:"
    echo ""
    echo "1) 完整初始化 (推荐)"
    echo "   - 更换镜像源"
    echo "   - 安装基础工具"
    echo "   - 系统优化"
    echo "   - SSH 配置"
    echo "   - 时区设置"
    echo "   - 系统清理"
    echo ""
    echo "2) 仅更换镜像源"
    echo "3) 仅安装基础工具"
    echo "4) 仅系统优化"
    echo "5) 仅配置 SSH"
    echo "6) 显示系统信息"
    echo "7) 查看日志文件"
    echo "8) 退出脚本"
    echo ""
}

# 完整初始化流程
full_initialization() {
    print_info "开始完整系统初始化..."

    # 1. 备份原始配置
    backup_sources

    # 2. 配置镜像源
    case $OS in
        ubuntu|debian)
            configure_ubuntu_mirrors || {
                print_warning "镜像源配置失败,继续其他步骤..."
            }
            ;;
        centos|rhel|rocky|almalinux)
            configure_centos_mirrors || {
                print_warning "镜像源配置失败,继续其他步骤..."
            }
            ;;
        *)
            print_warning "暂不支持该系统的镜像源配置"
            ;;
    esac

    # 3. 安装基础工具
    install_basic_tools

    # 4. 配置时区
    configure_timezone

    # 5. 配置语言环境(可选)
    if [[ -z "${NON_INTERACTIVE:-}" ]]; then
        configure_locale
    fi

    # 6. 配置 SSH
    configure_ssh

    # 7. 系统优化
    optimize_system

    # 8. 系统清理
    clean_system

    print_success "系统初始化完成!"

    # 显示系统信息
    show_system_info

    # 显示后续建议
    echo ""
    print_info "建议执行以下操作:"
    echo "1. 重启系统使所有配置生效: sudo reboot"
    echo "2. 检查系统更新: sudo apt-get upgrade 或 sudo yum update"
    echo "3. 查看详细日志: cat $LOG_FILE"
    echo ""
}

# 查看日志文件
view_log_file() {
    echo ""
    print_info "日志文件内容 (最后50行):"
    echo "=================================================="
    tail -50 "$LOG_FILE"
    echo "=================================================="
    echo ""
    print_info "完整日志文件路径: $LOG_FILE"
}

# 显示帮助信息
show_help() {
    echo ""
    echo "Linux 系统初始化脚本 v1.1"
    echo ""
    echo "用法: $0 [选项]"
    echo ""
    echo "选项:"
    echo "  --auto                  自动模式 (非交互式,使用默认配置)"
    echo "  --mirror=SOURCE         指定镜像源 (aliyun, tsinghua, ustc, huawei)"
    echo "  --non-interactive       非交互模式 (跳过所有确认)"
    echo "  --help                  显示此帮助信息"
    echo ""
    echo "示例:"
    echo "  sudo $0 --auto"
    echo "  sudo $0 --mirror=aliyun --non-interactive"
    echo ""
}

# 解析命令行参数
parse_arguments() {
    while [[ $# -gt 0 ]]; do
        case $1 in
            --auto)
                AUTO_MODE=1
                NON_INTERACTIVE=1
                MIRROR_ARG="aliyun"
                shift
                ;;
            --mirror=*)
                MIRROR_ARG="${1#*=}"
                shift
                ;;
            --non-interactive)
                NON_INTERACTIVE=1
                shift
                ;;
            --help|-h)
                show_help
                exit 0
                ;;
            *)
                print_error "未知参数: $1"
                show_help
                exit 1
                ;;
        esac
    done
}

# 主函数
main() {
    # 解析命令行参数
    parse_arguments "$@"

    # 显示横幅
    print_banner

    # 检查权限
    check_permissions

    # 检测操作系统
    detect_os

    # 检查必要命令
    check_command "curl" || error_exit "curl 安装失败"
    check_command "wget" || print_warning "wget 安装失败,部分功能可能受限"

    # 自动模式直接执行完整初始化
    if [[ -n "${AUTO_MODE:-}" ]]; then
        full_initialization
        exit 0
    fi

    # 交互式菜单
    while true; do
        show_menu
        read -rp "请选择操作 [1-8]: " choice

        case $choice in
            1)
                full_initialization
                break
                ;;
            2)
                backup_sources
                case $OS in
                    ubuntu|debian)
                        configure_ubuntu_mirrors
                        ;;
                    centos|rhel|rocky|almalinux)
                        configure_centos_mirrors
                        ;;
                esac
                ;;
            3)
                install_basic_tools
                ;;
            4)
                optimize_system
                ;;
            5)
                configure_ssh
                ;;
            6)
                show_system_info
                ;;
            7)
                view_log_file
                ;;
            8)
                print_info "退出脚本"
                echo "详细日志请查看: $LOG_FILE"
                exit 0
                ;;
            *)
                print_warning "无效选择,请重新输入"
                ;;
        esac

        # 询问是否继续
        if [[ $choice -ne 8 ]]; then
            echo ""
            read -rp "是否继续其他操作? [Y/n]: " continue_choice
            continue_choice=${continue_choice:-Y}
            if [[ ! $continue_choice =~ ^[Yy]$ ]]; then
                print_info "退出脚本"
                echo "详细日志请查看: $LOG_FILE"
                exit 0
            fi
        fi
    done
}

# 脚本入口点
main "$@"