Update image.sh

This commit is contained in:
starry
2025-12-17 22:55:32 +08:00
committed by GitHub
parent 4b077c203f
commit dbe8a78f21

View File

@@ -6,8 +6,10 @@
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# 检查 root 权限
check_root() {
if [ "$(id -u)" -ne 0 ]; then
echo -e "${RED}错误:必须使用 root 权限运行此脚本${NC}"
@@ -15,46 +17,122 @@ check_root() {
fi
}
# 检测地理位置
detect_region() {
echo -e "${BLUE}检测网络位置...${NC}"
local TRACE_URLS=(
"https://www.cloudflare.com/cdn-cgi/trace"
"https://www.visa.cn/cdn-cgi/trace"
)
local trace_info=""
for url in "${TRACE_URLS[@]}"; do
trace_info=$(curl -sSL --max-time 8 "$url" 2>/dev/null) && break
done
if echo "$trace_info" | grep -q '^loc=CN'; then
echo -e "${GREEN}CN 网络环境${NC}"
return 0
else
echo -e "${GREEN}非 CN 网络环境${NC}"
return 1
fi
}
# 切换软件源
change_mirrors() {
echo -e "${YELLOW}[0/5] 配置软件源${NC}"
if detect_region; then
echo -e "使用阿里云镜像..."
bash <(curl -sSL https://gitee.com/SuperManito/LinuxMirrors/raw/main/ChangeMirrors.sh) \
--source mirrors.aliyun.com \
--protocol http \
--use-intranet-source false \
--install-epel true \
--backup true \
--upgrade-software false \
--clean-cache false \
--ignore-backup-tips \
--pure-mode
else
echo -e "使用官方源..."
bash <(curl -sSL https://raw.githubusercontent.com/SuperManito/LinuxMirrors/main/ChangeMirrors.sh) \
--use-official-source true \
--protocol http \
--use-intranet-source false \
--install-epel true \
--backup true \
--upgrade-software false \
--clean-cache false \
--ignore-backup-tips \
--pure-mode
fi
if [ $? -ne 0 ]; then
echo -e "${YELLOW}警告:软件源切换失败,继续使用当前源${NC}"
else
apt update -qq
fi
}
# 二次确认
confirm_operation() {
echo -e "\n${RED}⚠️ 高危操作警告 ⚠️${NC}"
echo -e "${RED}此脚本将修改系统内核,可能导致:${NC}"
echo -e "${RED} • 系统无法启动(如果新内核不兼容)${NC}"
echo -e "${RED} • 网络驱动丢失(在特定云平台上)${NC}"
echo -e "${RED} • 需要控制台访问权限才能恢复${NC}"
echo -e "${RED} • 请务必备份重要数据再执行${NC}"
echo -e "\n${YELLOW}当前内核:${NC}$(uname -r)"
echo -e "${YELLOW}虚拟化:${NC}$(systemd-detect-virt 2>/dev/null || echo '未知')"
# 显示将要删除的 Cloud 内核
local cloud_pkgs=$(dpkg -l 2>/dev/null | awk '/linux-(image|headers)-[0-9].*cloud/ {print $2}')
if [ -n "$cloud_pkgs" ]; then
echo -e "\n${YELLOW}将要卸载的 Cloud 内核:${NC}"
echo "$cloud_pkgs" | sed 's/^/ /'
fi
echo ""
read -p "$(echo -e ${YELLOW}"确认继续?[y/N]: "${NC})" confirm
if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
echo -e "${GREEN}操作已取消${NC}"
exit 0
fi
echo -e "${GREEN}开始执行...${NC}\n"
}
# 检查当前内核
check_cloud_kernel() {
if ! uname -r | grep -q 'cloud'; then
echo -e "${GREEN}提示:系统已在标准内核运行 ($(uname -r))${NC}"
# 检查是否还有 Cloud 内核包
local cloud_pkgs=$(dpkg -l 2>/dev/null | awk '/linux-(image|headers)-[0-9].*cloud/ {print $2}')
if [ -n "$cloud_pkgs" ]; then
echo -e "${YELLOW}但系统中仍有 Cloud 内核包:${NC}"
echo "$cloud_pkgs" | sed 's/^/ /'
echo ""
read -p "$(echo -e ${YELLOW}"是否清理这些包?[y/N]: "${NC})" clean_confirm
if [[ "$clean_confirm" =~ ^[Yy]$ ]]; then
apt purge -y $cloud_pkgs
apt autoremove -y --purge
update-grub
echo -e "${GREEN}清理完成${NC}"
fi
fi
exit 0
fi
}
purge_cloud_kernel() {
echo -e "${YELLOW}步骤1/4彻底移除 Cloud 内核...${NC}"
# 安装标准内核
install_standard_kernel() {
echo -e "${YELLOW}[1/5] 安装标准内核${NC}"
# 找出所有 Cloud 内核包
local cloud_pkgs=$(dpkg -l | awk '/linux-(image|headers)-[0-9].*cloud/ {print $2}')
if [ -n "$cloud_pkgs" ]; then
echo -e "正在卸载: ${cloud_pkgs}"
apt purge -y $cloud_pkgs
apt autoremove -y --purge
else
echo -e "${GREEN}提示:未找到 Cloud 内核包${NC}"
fi
}
lock_cloud_kernel() {
echo -e "${YELLOW}步骤2/4锁定 Cloud 内核...${NC}"
# 检查是否还有额外的 Cloud 内核包,如果有则标记为 hold
cloud_kernels=$(apt list --installed 2>/dev/null | grep -i 'linux-image' | grep -i 'cloud' | cut -d'/' -f1)
if [ -n "$cloud_kernels" ]; then
echo "找到以下 Cloud 内核包,正在锁定:$cloud_kernels"
apt-mark hold $cloud_kernels
else
echo -e "${GREEN}提示:未找到任何 Cloud 内核包,跳过锁定步骤。${NC}"
fi
}
force_install_standard() {
echo -e "${YELLOW}步骤3/4安装标准内核...${NC}"
# 根据系统类型选择包名
local image_pkg="linux-image-amd64"
local headers_pkg="linux-headers-amd64"
@@ -62,66 +140,163 @@ force_install_standard() {
image_pkg="linux-image-generic"
headers_pkg="linux-headers-generic"
fi
# 强制安装并跳过配置提问
DEBIAN_FRONTEND=noninteractive apt install -y --reinstall --allow-downgrades \
"$image_pkg" "$headers_pkg"
# 确保 initramfs 更新
local std_kernel=$(ls /boot/vmlinuz-* | grep -v cloud | sort -V | tail -1 | sed 's|/boot/vmlinuz-||')
update-initramfs -u -k "$std_kernel"
echo -e "正在安装 $image_pkg $headers_pkg ..."
DEBIAN_FRONTEND=noninteractive apt install -y --reinstall \
"$image_pkg" "$headers_pkg" 2>&1 | grep -E "正在|Setting up|unpacking|Processing|配置|解包"
if [ ${PIPESTATUS[0]} -ne 0 ]; then
echo -e "${RED}错误:标准内核安装失败!${NC}"
exit 1
fi
local std_kernel=$(ls /boot/vmlinuz-* 2>/dev/null | grep -v cloud | sort -V | tail -1 | sed 's|/boot/vmlinuz-||')
if [ -n "$std_kernel" ]; then
echo -e "更新 initramfs: $std_kernel"
update-initramfs -u -k "$std_kernel" 2>&1 | grep -v "^I:"
fi
echo -e "${GREEN}✓ 标准内核安装完成: $std_kernel${NC}"
}
nuclear_grub_update() {
echo -e "${YELLOW}步骤4/4重建 GRUB...${NC}"
# 卸载所有 Cloud 内核
remove_cloud_kernels() {
echo -e "${YELLOW}[2/5] 卸载所有 Cloud 内核${NC}"
# 备份原配置
mkdir -p /root/grub_backup
cp -a /boot/grub /root/grub_backup/grub.bak.$(date +%s)
# 找出所有 Cloud 内核包(包括 image 和 headers
local cloud_pkgs=$(dpkg -l 2>/dev/null | awk '/linux-(image|headers|modules)-[0-9].*cloud/ {print $2}')
# 生成干净的 GRUB 配置
cat > /etc/default/grub <<'EOF'
GRUB_DEFAULT=0
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR=lsb_release -i -s 2> /dev/null || echo Debian
GRUB_CMDLINE_LINUX_DEFAULT="quiet"
GRUB_CMDLINE_LINUX=""
GRUB_DISABLE_OS_PROBER=true
GRUB_DISABLE_RECOVERY=true
EOF
# 完全重建配置
grub-mkconfig -o /boot/grub/grub.cfg
if [ -z "$cloud_pkgs" ]; then
echo -e "${YELLOW}未找到 Cloud 内核包${NC}"
return 0
fi
# 确保使用第一个菜单项
grub-set-default 0
update-grub
echo -e "正在卸载以下包:"
echo "$cloud_pkgs" | sed 's/^/ /'
# 特殊处理 UEFI 系统
if [ -d /sys/firmware/efi ]; then
echo -e "检测到 UEFI 系统,更新引导加载程序..."
grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=debian --recheck
# 解锁所有 Cloud 内核
apt-mark unhold $cloud_pkgs > /dev/null 2>&1
# 彻底卸载
DEBIAN_FRONTEND=noninteractive apt purge -y $cloud_pkgs 2>&1 | grep -E "正在|Removing|移除|卸载"
if [ ${PIPESTATUS[0]} -ne 0 ]; then
echo -e "${YELLOW}警告:部分包卸载失败,继续执行...${NC}"
fi
# 清理残留
apt autoremove -y --purge > /dev/null 2>&1
# 验证是否清理干净
local remaining=$(dpkg -l 2>/dev/null | awk '/linux-(image|headers|modules)-[0-9].*cloud/ {print $2}')
if [ -n "$remaining" ]; then
echo -e "${YELLOW}警告:以下包未能完全卸载:${NC}"
echo "$remaining" | sed 's/^/ /'
else
echo -e "${GREEN}✓ 所有 Cloud 内核已卸载${NC}"
fi
}
# 配置 GRUB
configure_grub() {
echo -e "${YELLOW}[3/5] 配置 GRUB${NC}"
mkdir -p /root/grub_backup
cp /etc/default/grub /root/grub_backup/grub.default.$(date +%s) 2>/dev/null
# 使用简单的 GRUB_DEFAULT=0
cat > /etc/default/grub <<'EOF'
GRUB_DEFAULT=0
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT="quiet"
GRUB_CMDLINE_LINUX=""
GRUB_DISABLE_OS_PROBER=true
EOF
echo -e "${GREEN}✓ GRUB 配置完成GRUB_DEFAULT=0${NC}"
}
# 更新 GRUB
update_grub_config() {
echo -e "${YELLOW}[4/5] 更新 GRUB${NC}"
cp -a /boot/grub /root/grub_backup/grub.bak.$(date +%s) 2>/dev/null
echo -e "重新生成 GRUB 配置..."
update-grub 2>&1 | grep -E "Found|Generating|生成|找到"
# 明确设置默认启动项为 0
grub-set-default 0
if [ -d /sys/firmware/efi ]; then
echo -e "更新 UEFI 引导..."
grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=debian --recheck > /dev/null 2>&1
fi
echo -e "${GREEN}✓ GRUB 更新完成,默认启动第一个内核${NC}"
}
# 验证配置
verify_configuration() {
echo -e "${YELLOW}[5/5] 验证配置${NC}"
echo -e "${BLUE}当前内核:${NC}$(uname -r)"
echo -e "${BLUE}系统中的内核:${NC}"
local all_kernels=$(dpkg -l 2>/dev/null | grep -E 'linux-image-[0-9]' | awk '{print $2}')
if [ -n "$all_kernels" ]; then
echo "$all_kernels" | sed 's/^/ /'
else
echo " 未找到内核包"
fi
echo -e "${BLUE}GRUB 启动顺序前3项${NC}"
awk -F "'" '/menuentry / && $0 !~ /submenu/ {
count++
if (count <= 3) {
print " " count-1 ": " $2
}
}' /boot/grub/grub.cfg 2>/dev/null
echo -e "${BLUE}GRUB 默认设置:${NC} $(grep "^GRUB_DEFAULT=" /etc/default/grub)"
echo -e "${GREEN}✓ 验证完成${NC}"
}
# 主函数
main() {
echo -e "\n${GREEN}=== Debian/Ubuntu 内核切换脚本 ===${NC}"
echo -e "\n${GREEN}Debian/Ubuntu 内核切换脚本${NC}\n"
check_root
check_cloud_kernel
confirm_operation
# 执行核心修复步骤
purge_cloud_kernel
lock_cloud_kernel
force_install_standard
nuclear_grub_update
change_mirrors
install_standard_kernel
remove_cloud_kernels
configure_grub
update_grub_config
verify_configuration
# 最终验证
echo -e "\n${GREEN}=== 操作完成 ===${NC}"
echo -e "请手动重启系统:"
echo -e "1. 重启系统: ${YELLOW}reboot${NC}"
echo -e "2. 检查内核: ${YELLOW}uname -r${NC}"
touch /root/.kernel_switch_success
echo -e "\n${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${GREEN}操作完成!${NC}"
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "\n${YELLOW}重要提示:${NC}"
echo -e " • 所有 Cloud 内核已卸载"
echo -e " • 备份位置:${BLUE}/root/grub_backup/${NC}\n"
echo -e "${YELLOW}下一步:${NC}"
echo -e " 1. 执行 ${BLUE}reboot${NC} 重启系统"
echo -e " 2. 重启后运行 ${BLUE}uname -r${NC} 确认内核"
read -p "$(echo -e ${YELLOW}"立即重启?[y/N]: "${NC})" reboot_now
if [[ "$reboot_now" =~ ^[Yy]$ ]]; then
echo -e "${GREEN}正在重启...${NC}"
sleep 2
reboot
fi
}
main "$@"