DeepSeek生成的关于openeuler系统自动编译安装kernel内核脚本
完整脚本请下载附件
deepseek_Install_Kernel_Full.sh.zip
最终脚本
1,提问:
优化脚本
2,AI回复
我们被要求“优化脚本”。用户之前已经有一个能够工作的脚本,但在运行中遇到了证书问题,我们已解决。现在需要基于解决后的脚本进行优化。
需要分析可能优化哪些方面:
代码健壮性:添加错误处理、日志记录、路径检查。
性能:使用更多并行编译、增量编译?不能,因为是全量编译。
灵活性:可配置内核版本、URL、安装路径等参数。
交互性:减少交互,全自动。
清理:编译完成后清理源码包以节省磁盘空间?可能可选。
功能增强:检查磁盘空间,显示进度,备份旧内核配置,自动确认。
依赖安装:添加必要依赖,避免重复安装,使用检查。
错误处理:set -e 已存在,可以添加 trap 清理。
日志:将输出重定向到日志文件同时输出到终端。
检查系统是否为 openEuler 2509,给出警告。
检查内核版本是否与当前运行冲突。
支持恢复默认内核等。
要求是“优化脚本”,应生成一个改进的脚本版本,并解释优化点。
因为上一次回答中已经包含了一个修复脚本,现在可以在此基础上优化。
注意对话历史,最后用户说“优化脚本”。那么我们输出优化后的脚本并说明改进点。
确保脚本在 openEuler 2509 上可用,兼容性。
优化建议:
添加颜色输出,更友好的日志。
将内核下载地址设为变量,便于修改。
添加依赖包检查,仅安装缺失的。
检查是否有足够磁盘空间(比如至少10GB)。
编译时使用
-j$(nproc)但避免内存不足,可以加限制。在
make时添加V=1以便出错时看到详细信息?或者默认不开启,但提供选项。优化脚本可考虑在出错时自动开启详细模式,但较复杂。增加
time命令统计耗时。完成后可选删除源码包和解压目录,或保留。
添加
set -o pipefail使管道错误也能被捕获。检测内核是否已经安装,避免重复安装。
将编译日志保存到文件,方便排查。
在 grubby 设置默认前,验证新内核文件存在。
增加回滚功能:备份旧内核的 grub 配置?可选。
使用
exec > >(tee ...)记录日志。
综上,我会提供一个优化版脚本,并注释说明优化点。
已对脚本进行了多方面的优化,增强了可靠性、灵活性和用户友好性。以下是优化后的脚本:
#!/bin/bash
# ============================================================
# 优化版:在 openEuler 2509 上编译安装 Linux Kernel 7.0.9
# 功能:自动下载、配置、编译、安装、设为默认启动
# ============================================================
set -euo pipefail
# -------------------------- 可配置变量 --------------------------
KERNEL_VERSION="${1:-7.0.9}" # 可通过命令行参数指定内核版本
KERNEL_SOURCE="linux-${KERNEL_VERSION}"
KERNEL_ARCHIVE="${KERNEL_SOURCE}.tar.gz"
KERNEL_URL="https://mirrors.nju.edu.cn/kernel.org/linux/kernel/v7.x/${KERNEL_ARCHIVE}"
WORK_DIR="/usr/src"
BOOT_DIR="/boot"
BUILD_LOG="${WORK_DIR}/kernel_build_${KERNEL_VERSION}.log" # 编译日志
DISK_SPACE_MIN_MB=10240 # 至少 10GB 剩余空间
# -------------------------- 颜色定义 --------------------------
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# -------------------------- 辅助函数 --------------------------
print_info() { echo -e "${GREEN}[INFO]${NC} $*"; }
print_warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
print_error() { echo -e "${RED}[ERROR]${NC} $*"; exit 1; }
check_root() {
if [ "$EUID" -ne 0 ]; then
print_error "请使用 root 权限运行此脚本。"
fi
}
check_os() {
if [ ! -f /etc/openEuler-release ]; then
print_warn "未检测到 openEuler 系统,脚本可能运行异常。"
else
print_info "系统版本: $(cat /etc/openEuler-release)"
fi
}
check_space() {
local available_mb
available_mb=$(df --output=avail -m "$WORK_DIR" | tail -1)
if [ "$available_mb" -lt "$DISK_SPACE_MIN_MB" ]; then
print_error "${WORK_DIR} 剩余空间不足 ${DISK_SPACE_MIN_MB}MB,当前仅 ${available_mb}MB。"
fi
print_info "磁盘空间检查通过 (可用 ${available_mb}MB)"
}
install_dependencies() {
print_info "安装编译依赖..."
dnf makecache -q
local pkgs=(
gcc make flex bison openssl-devel elfutils-libelf-devel
ncurses-devel bc perl perl-devel tar wget bzip2 dwarves grubby
kernel-devel-$(uname -r) dnf-plugins-core
)
# 安装所有包,缺失的安装,已存在的跳过
dnf install -y "${pkgs[@]}" 2>/dev/null || true
print_info "依赖安装完成"
}
download_source() {
cd "$WORK_DIR"
if [ -f "$KERNEL_ARCHIVE" ]; then
print_warn "源码包 ${KERNEL_ARCHIVE} 已存在,将被覆盖。"
rm -f "$KERNEL_ARCHIVE"
fi
print_info "下载内核源码:${KERNEL_URL}"
wget -q --show-progress "$KERNEL_URL" || print_error "下载失败,请检查网络或 URL。"
}
extract_source() {
print_info "解压源码..."
tar -xzf "$KERNEL_ARCHIVE"
if [ ! -d "$KERNEL_SOURCE" ]; then
print_error "解压失败,未找到目录 ${KERNEL_SOURCE}"
fi
cd "$KERNEL_SOURCE"
}
configure_kernel() {
print_info "配置内核..."
# 1. 优先使用当前运行内核的配置
local current_config="/boot/config-$(uname -r)"
if [ -f "$current_config" ]; then
cp "$current_config" .config
print_info "已复制当前内核配置(${current_config})"
else
make defconfig
print_info "使用默认 defconfig"
fi
make olddefconfig
# 2. 清除 openEuler 特有的证书路径,避免编译报错
scripts/config --set-str CONFIG_SYSTEM_TRUSTED_KEYS ""
scripts/config --set-str CONFIG_SYSTEM_REVOCATION_KEYS ""
scripts/config --set-str CONFIG_SYSTEM_EXTRA_CERTIFICATE ""
# 3. 禁用 Rust 支持(openEuler 最小化安装通常没有 Rust 工具链)
scripts/config --disable CONFIG_RUST
scripts/config --disable CONFIG_RUST_IS_AVAILABLE
# 使修改生效
make olddefconfig
print_info "内核配置完成"
}
build_kernel() {
local cpu_cores
cpu_cores=$(nproc)
print_info "开始编译内核(使用 ${cpu_cores} 线程),日志同时写入 ${BUILD_LOG}"
# 编译并记录详细日志,方便排错
make -j"$cpu_cores" V=1 2>&1 | tee "$BUILD_LOG"
if [ ${PIPESTATUS[0]} -ne 0 ]; then
print_error "内核编译失败,请查看日志:${BUILD_LOG}"
fi
print_info "编译完成"
}
install_kernel() {
print_info "安装内核模块及内核..."
make modules_install
make install
}
set_default_boot() {
print_info "设置新内核为默认启动项..."
# 查找新内核镜像(可能带架构后缀)
local new_kernel
new_kernel=$(ls "${BOOT_DIR}/vmlinuz-${KERNEL_VERSION}"* 2>/dev/null | head -1)
if [ -z "$new_kernel" ]; then
print_error "未找到新内核文件 ${BOOT_DIR}/vmlinuz-${KERNEL_VERSION}*"
fi
grubby --set-default="$new_kernel"
if command -v grub2-mkconfig &>/dev/null; then
grub2-mkconfig -o /boot/grub2/grub.cfg
fi
print_info "默认内核已设置为:${new_kernel}"
}
cleanup_optional() {
print_info "清理:可选择删除源码包与编译目录以节省空间。"
read -p "是否删除源码包 ${KERNEL_ARCHIVE}?[y/N] " -r ans
if [[ "$ans" =~ ^[Yy]$ ]]; then
rm -f "${WORK_DIR}/${KERNEL_ARCHIVE}"
print_info "已删除源码包"
fi
read -p "是否删除编译目录 ${WORK_DIR}/${KERNEL_SOURCE}?[y/N] " -r ans
if [[ "$ans" =~ ^[Yy]$ ]]; then
rm -rf "${WORK_DIR}/${KERNEL_SOURCE}"
print_info "已删除编译目录"
fi
}
# -------------------------- 主流程 --------------------------
main() {
print_info "开始安装 Linux Kernel ${KERNEL_VERSION}"
check_root
check_os
check_space
install_dependencies
download_source
extract_source
configure_kernel
build_kernel
install_kernel
set_default_boot
echo ""
print_info "内核 ${KERNEL_VERSION} 安装完成!"
print_info "请执行 reboot 重启以进入新内核。"
echo ""
cleanup_optional
}
main "$@"3,优化点说明
错误处理增强
set -euo pipefail确保任何命令失败、未定义变量、管道错误都能立即退出,避免带伤运行。参数化内核版本可通过命令行参数指定(默认 7.0.9),例如:
./script.sh 7.0.10日志记录编译输出完整保存至
/usr/src/kernel_build_*.log,便于失败后排查。前置检查
系统是否为 openEuler(给出警告而非强制退出)
工作目录至少 10GB 剩余空间(避免编译中断)
交互与清理编译完成后可选择删除源码包和编译目录,释放磁盘空间。
色彩与友好输出使用颜色标记信息、警告、错误,阅读更直观。
安全改进
wget -q --show-progress隐藏多余信息依赖安装时使用数组,避免遗漏
make olddefconfig多次调用确保配置一致性健壮性
检查解压后目录是否存在
编译失败时直接定位日志文件
设置默认启动前严格校验内核文件
目录 返回
首页