CentOS 7 内核升级脚本 (kernel-lt-5.4)

脚本内容,均无加密可放心使用,如果不想看可以拉到最后看使用脚本

#!/bin/bash
# =====================================================
# CentOS 7 内核一键安装脚本 - 源修复版
# 版本: 3.0
# 描述: 修复CentOS 7源问题,直接从网络下载并安装kernel-lt-5.4.278
# =====================================================

# 设置严格模式(兼容老旧系统)
set -eo pipefail
set +u  # 避免未定义变量报错

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
WHITE='\033[1;37m'
NC='\033[0m'

# 配置常量
readonly KERNEL_VERSION="5.4.278-1.el7.elrepo.x86_64"
readonly KERNEL_PACKAGE="kernel-lt-${KERNEL_VERSION}.rpm"
readonly DOWNLOAD_URL="http://linux.6wd.cn/${KERNEL_PACKAGE}"
readonly LOG_FILE="/var/log/kernel-install-$(date +%Y%m%d-%H%M%S).log"
readonly BACKUP_DIR="/root/kernel-backup-$(date +%Y%m%d-%H%M%S)"

# 错误退出函数
error_exit() {
    echo -e "\n${RED}╔════════════════════════════════════════════════════════════════╗${NC}"
    echo -e "${RED}║                         ❌ 安装失败 ❌                          ║${NC}"
    echo -e "${RED}╠════════════════════════════════════════════════════════════════╣${NC}"
    echo -e "${RED}║${WHITE} 错误: $1${NC}"
    echo -e "${RED}║${WHITE} 日志: $LOG_FILE${NC}"
    echo -e "${RED}╚════════════════════════════════════════════════════════════════╝${NC}"
    exit 1
}

# 清理函数
cleanup() {
    if [[ -f "$KERNEL_PACKAGE" ]]; then
        rm -f "$KERNEL_PACKAGE" 2>/dev/null
        echo -e "${BLUE}[清理] 已删除临时文件: $KERNEL_PACKAGE${NC}" | tee -a "$LOG_FILE"
    fi
}

# 设置陷阱
trap cleanup EXIT
trap 'echo -e "\n${RED}[中断] 脚本被用户终止${NC}" | tee -a "$LOG_FILE"; exit 130' INT TERM

# 打印横幅
print_banner() {
    clear 2>/dev/null || true
    echo -e "${PURPLE}╔════════════════════════════════════════════════════════════════╗${NC}"
    echo -e "${PURPLE}║${WHITE}${BOLD}          CentOS 7 内核一键安装脚本 (源修复版)            ${PURPLE}║${NC}"
    echo -e "${PURPLE}╠════════════════════════════════════════════════════════════════╣${NC}"
    printf "${PURPLE}║${WHITE} 目标内核: ${GREEN}%-45s${PURPLE}║${NC}\n" "$KERNEL_VERSION"
    printf "${PURPLE}║${WHITE} 日志文件: ${BLUE}%-45s${PURPLE}║${NC}\n" "$LOG_FILE"
    echo -e "${PURPLE}╚════════════════════════════════════════════════════════════════╝${NC}"
    echo ""
}

# 修复CentOS 7源
fix_centos_repo() {
    echo -e "${BLUE}[1/7] 修复CentOS 7 yum源...${NC}" | tee -a "$LOG_FILE"
  
    # 备份原有源
    if [[ -d /etc/yum.repos.d ]]; then
        mkdir -p /etc/yum.repos.d/backup
        mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/backup/ 2>/dev/null || true
    fi
  
    # 使用阿里云镜像源(CentOS 7 vault)
    cat > /etc/yum.repos.d/CentOS7-Aliyun.repo << 'EOF'
[base]
name=CentOS-7 - Base - Aliyun
baseurl=http://mirrors.aliyun.com/centos-vault/7.9.2009/os/\$basearch/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos-vault/RPM-GPG-KEY-CentOS-7
enabled=1

[updates]
name=CentOS-7 - Updates - Aliyun
baseurl=http://mirrors.aliyun.com/centos-vault/7.9.2009/updates/\$basearch/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos-vault/RPM-GPG-KEY-CentOS-7
enabled=1

[extras]
name=CentOS-7 - Extras - Aliyun
baseurl=http://mirrors.aliyun.com/centos-vault/7.9.2009/extras/\$basearch/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos-vault/RPM-GPG-KEY-CentOS-7
enabled=1

[epel]
name=Extra Packages for Enterprise Linux 7 - \$basearch
baseurl=http://mirrors.aliyun.com/epel/7/\$basearch
gpgcheck=0
enabled=1
EOF

    # 添加elrepo源(用于内核)
    rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org 2>/dev/null || true
    cat > /etc/yum.repos.d/elrepo.repo << 'EOF'
[elrepo]
name=ELRepo.org Community Enterprise Linux Repository - el7
baseurl=http://mirrors.aliyun.com/elrepo/elrepo/el7/\$basearch/
        http://elrepo.org/linux/elrepo/el7/\$basearch/
enabled=1
gpgcheck=1
gpgkey=https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
protect=0

[elrepo-kernel]
name=ELRepo.org Community Enterprise Linux Kernel Repository - el7
baseurl=http://mirrors.aliyun.com/elrepo/kernel/el7/\$basearch/
        http://elrepo.org/linux/kernel/el7/\$basearch/
enabled=1
gpgcheck=1
gpgkey=https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
protect=0
EOF

    # 清理缓存
    yum clean all >> "$LOG_FILE" 2>&1
    yum makecache >> "$LOG_FILE" 2>&1
  
    echo -e "${GREEN}✓ yum源修复完成${NC}" | tee -a "$LOG_FILE"
}

# 检查root权限
check_root() {
    echo -e "${BLUE}[2/7] 检查权限...${NC}" | tee -a "$LOG_FILE"
    if [[ $EUID -ne 0 ]]; then
        error_exit "此脚本必须以root权限运行"
    fi
    echo -e "${GREEN}✓ root权限验证通过${NC}" | tee -a "$LOG_FILE"
}

# 检查系统
check_system() {
    echo -e "${BLUE}[3/7] 检查系统版本...${NC}" | tee -a "$LOG_FILE"
  
    if [[ ! -f /etc/centos-release ]]; then
        error_exit "此脚本仅支持CentOS系统"
    fi
  
    local centos_version=$(cat /etc/centos-release | grep -oP '[0-9]+' | head -1)
    if [[ "$centos_version" != "7" ]]; then
        error_exit "此脚本仅支持CentOS 7,当前版本: $(cat /etc/centos-release)"
    fi
  
    local arch=$(uname -m)
    if [[ "$arch" != "x86_64" ]]; then
        error_exit "此脚本仅支持x86_64架构,当前架构: $arch"
    fi
  
    echo -e "${GREEN}✓ 系统版本: $(cat /etc/centos-release) ($arch)${NC}" | tee -a "$LOG_FILE"
}

# 检查磁盘空间
check_disk_space() {
    echo -e "${BLUE}[4/7] 检查磁盘空间...${NC}" | tee -a "$LOG_FILE"
  
    BOOT_FREE=$(df -m /boot | awk 'NR==2 {print $4}')
    if [[ "$BOOT_FREE" -lt 200 ]]; then
        error_exit "/boot分区空间不足(可用: ${BOOT_FREE}MB),需要至少200MB"
    fi
    echo -e "${GREEN}✓ /boot分区可用: ${BOOT_FREE}MB${NC}" | tee -a "$LOG_FILE"
}

# 下载内核文件
download_kernel() {
    echo -e "${BLUE}[5/7] 开始下载内核文件...${NC}" | tee -a "$LOG_FILE"
    echo "下载地址: $DOWNLOAD_URL" | tee -a "$LOG_FILE"
  
    # 选择下载工具
    if command -v wget &>/dev/null; then
        echo "使用 wget 下载..." | tee -a "$LOG_FILE"
        wget -O "$KERNEL_PACKAGE" "$DOWNLOAD_URL" --progress=bar:force 2>&1 | tee -a "$LOG_FILE"
    elif command -v curl &>/dev/null; then
        echo "使用 curl 下载..." | tee -a "$LOG_FILE"
        curl -L -o "$KERNEL_PACKAGE" "$DOWNLOAD_URL" --progress-bar 2>&1 | tee -a "$LOG_FILE"
    else
        error_exit "未找到 wget 或 curl,无法下载"
    fi
  
    # 验证下载
    if [[ ! -f "$KERNEL_PACKAGE" ]]; then
        error_exit "下载失败:文件未找到"
    fi
  
    # 兼容Linux/BSD的stat命令
    FILE_SIZE=$(stat -c%s "$KERNEL_PACKAGE" 2>/dev/null)
    if [[ -z "$FILE_SIZE" ]]; then
        FILE_SIZE=$(stat -f%z "$KERNEL_PACKAGE" 2>/dev/null)
    fi
  
    if [[ -z "$FILE_SIZE" || "$FILE_SIZE" -lt 10000000 ]]; then
        error_exit "下载文件不完整(大小: ${FILE_SIZE:-0} 字节)"
    fi
    echo -e "${GREEN}✓ 下载成功,文件大小: $((FILE_SIZE/1024/1024))MB${NC}" | tee -a "$LOG_FILE"
}

# 安装依赖
install_dependencies() {
    echo -e "${BLUE}[6/7] 安装依赖包...${NC}" | tee -a "$LOG_FILE"
  
    # 先安装epel-release
    yum install -y epel-release >> "$LOG_FILE" 2>&1 || true
  
    # 安装必要的工具
    local packages=(
        "grub2-tools"
        "coreutils"
        "numfmt"
        "file"
        "which"
    )
  
    local failed=0
    for pkg in "${packages[@]}"; do
        echo -n "  安装 $pkg... " | tee -a "$LOG_FILE"
        if yum install -y "$pkg" >> "$LOG_FILE" 2>&1; then
            echo -e "${GREEN}成功${NC}" | tee -a "$LOG_FILE"
        else
            echo -e "${YELLOW}跳过${NC}" | tee -a "$LOG_FILE"
        fi
    done
  
    echo -e "${GREEN}✓ 依赖安装完成${NC}" | tee -a "$LOG_FILE"
}

# 安装内核
install_kernel() {
    echo -e "${BLUE}[7/7] 安装内核...${NC}" | tee -a "$LOG_FILE"
  
    # 尝试yum安装
    echo "尝试使用yum安装..." | tee -a "$LOG_FILE"
    if yum localinstall -y "$KERNEL_PACKAGE" >> "$LOG_FILE" 2>&1; then
        echo -e "${GREEN}✓ yum安装成功${NC}" | tee -a "$LOG_FILE"
    else
        echo -e "${YELLOW}⚠ yum安装失败,尝试rpm强制安装...${NC}" | tee -a "$LOG_FILE"
    
        # 安装内核依赖
        yum install -y elfutils-libelf-devel >> "$LOG_FILE" 2>&1 || true
    
        # rpm强制安装
        rpm -ivh --replacepkgs "$KERNEL_PACKAGE" --nodeps >> "$LOG_FILE" 2>&1 || {
            error_exit "内核安装失败,请检查日志: $LOG_FILE"
        }
        echo -e "${GREEN}✓ rpm安装成功${NC}" | tee -a "$LOG_FILE"
    fi
  
    # 验证安装
    if rpm -q "kernel-lt-${KERNEL_VERSION}" &>/dev/null; then
        echo -e "${GREEN}✓ 内核安装验证通过${NC}" | tee -a "$LOG_FILE"
    else
        error_exit "内核安装验证失败:rpm数据库中未找到"
    fi
}

# 配置GRUB
configure_grub() {
    echo -e "${BLUE}[8/8] 配置GRUB引导...${NC}" | tee -a "$LOG_FILE"
  
    GRUB_CFG="/boot/grub2/grub.cfg"
    if [[ ! -f "$GRUB_CFG" ]]; then
        error_exit "GRUB配置文件不存在: $GRUB_CFG"
    fi
  
    # 获取GRUB菜单项
    GRUB_ENTRIES=$(awk -F\' '$1=="menuentry " {print i++ " : " $2}' "$GRUB_CFG" 2>/dev/null)
    if [[ -z "$GRUB_ENTRIES" ]]; then
        error_exit "无法读取GRUB菜单项"
    fi
  
    # 查找新内核索引
    NEW_INDEX=$(echo "$GRUB_ENTRIES" | grep -n "$KERNEL_VERSION" | head -1 | cut -d: -f1)
    if [[ -z "$NEW_INDEX" ]]; then
        KERNEL_MAIN_VER="${KERNEL_VERSION%%-*}"
        NEW_INDEX=$(echo "$GRUB_ENTRIES" | grep -n "$KERNEL_MAIN_VER" | head -1 | cut -d: -f1)
        echo -e "${YELLOW}⚠ 使用模糊匹配找到内核索引${NC}" | tee -a "$LOG_FILE"
    fi
  
    # 转换为0-based索引
    if [[ -n "$NEW_INDEX" ]]; then
        NEW_INDEX=$((NEW_INDEX - 1))
        echo -e "${GREEN}✓ 找到新内核GRUB索引: $NEW_INDEX${NC}" | tee -a "$LOG_FILE"
    else
        NEW_INDEX=0
        echo -e "${YELLOW}⚠ 未找到新内核索引,使用默认索引0${NC}" | tee -a "$LOG_FILE"
    fi
  
    # 设置默认启动项
    if grub2-set-default "$NEW_INDEX" >> "$LOG_FILE" 2>&1; then
        echo -e "${GREEN}✓ 默认启动项设置成功${NC}" | tee -a "$LOG_FILE"
    else
        echo -e "${YELLOW}⚠ grub2-set-default失败,尝试手动设置...${NC}" | tee -a "$LOG_FILE"
        GRUBENV="/boot/grub2/grubenv"
        if [[ -f "$GRUBENV" ]]; then
            cp -a "$GRUBENV" "${GRUBENV}.backup"
            if grep -q '^saved_entry=' "$GRUBENV"; then
                sed -i "s/^saved_entry=.*/saved_entry=$NEW_INDEX/" "$GRUBENV"
            else
                echo "saved_entry=$NEW_INDEX" >> "$GRUBENV"
            fi
            echo -e "${GREEN}✓ 手动设置成功${NC}" | tee -a "$LOG_FILE"
        fi
    fi
  
    # 重新生成GRUB配置
    grub2-mkconfig -o "$GRUB_CFG" >> "$LOG_FILE" 2>&1
    echo -e "${GREEN}✓ GRUB配置已更新${NC}" | tee -a "$LOG_FILE"
}

# 显示完成信息
show_completion() {
    echo -e "\n${GREEN}╔════════════════════════════════════════════════════════════════╗${NC}"
    echo -e "${GREEN}║${WHITE}${BOLD}                      ✅ 安装成功!                          ${GREEN}║${NC}"
    echo -e "${GREEN}╠════════════════════════════════════════════════════════════════╣${NC}"
    echo -e "${GREEN}║${WHITE}  当前内核: ${NC}$(uname -r)" | tee -a "$LOG_FILE"
    echo -e "${GREEN}║${WHITE}  新内核:   ${GREEN}$KERNEL_VERSION${NC}" | tee -a "$LOG_FILE"
    echo -e "${GREEN}║${WHITE}  日志文件: ${BLUE}$LOG_FILE${NC}" | tee -a "$LOG_FILE"
    echo -e "${GREEN}╚════════════════════════════════════════════════════════════════╝${NC}"
    echo ""
  
    # 询问重启
    echo -ne "${YELLOW}是否立即重启系统?${NC} (y/n): "
    read -r reboot_choice
    if [[ "$reboot_choice" =~ ^[Yy]$ ]]; then
        echo -e "${BLUE}系统将在5秒后重启...${NC}"
        echo -e "${RED}按 Ctrl+C 取消重启${NC}"
        sleep 5
        sync && reboot
    else
        echo -e "${BLUE}请手动执行 'reboot' 重启系统${NC}"
        echo -e "${BLUE}重启后执行 'uname -r' 验证内核版本${NC}"
    fi
}

# ========== 主函数 ==========
main() {
    print_banner
  
    # 执行步骤
    check_root
    check_system
    check_disk_space
    fix_centos_repo      # 新增:修复yum源
    download_kernel
    install_dependencies
    install_kernel
    configure_grub
  
    # 完成
    show_completion
}

# ========== 执行主函数 ==========
main "$@"

✨ 主要修复内容

1. 修复yum源问题 (新增 fix_centos_repo 函数)

  • 使用阿里云镜像源替换失效的腾讯云源
  • 添加elrepo源用于内核支持
  • 自动备份原有源配置

2. 增强依赖安装 (改进 install_dependencies 函数)

  • 即使部分依赖安装失败也能继续
  • 添加必要工具如 numfmtfile
  • 更详细的安装状态显示

3. 改进错误处理

  • 更友好的错误提示界面
  • 详细的步骤显示
  • 添加8个步骤的完整流程

4. 添加美化功能

  • 使用Unicode边框
  • 彩色进度显示
  • 清晰的步骤分隔

📥 使用方法

# 直接运行(会自动修复源问题)
bash <(curl -s http://linux.6wd.cn/up.sh)

# 或者下载后运行
curl -o up.sh http://linux.6wd.cn/up.sh
chmod +x up.sh
./up.sh

这个版本会自动修复 yum 源问题,使用阿里云镜像,确保依赖包能正常下载!