#!/bin/bash # prerm - 卸载前卸载内核模块 set -e # 当脚本由 dpkg 触发时,$DPKG_MAIN_TSN_PACKAGE 通常可用 PACKAGE_NAME="${DPKG_MAIN_TSN_PACKAGE}" if [ -z "$PACKAGE_NAME" ]; then SCRIPT_NAME=$(basename "$0") PACKAGE_NAME=$(echo "$SCRIPT_NAME" | sed 's/\.postinst$//' | sed 's/\.prerm$//') fi # 从 dpkg 数据库获取版本 if [ -n "$PACKAGE_NAME" ]; then PACKAGE_VERSION=$(dpkg-query -W -f='${Version}' "$PACKAGE_NAME" 2>/dev/null) # 去掉 Debian 修订号(-1, -2, -ubuntu1 等) PACKAGE_VERSION=$(echo "$PACKAGE_VERSION" | sed 's/-.*$//') fi DKMS_SRC_DIR="/usr/src/${PACKAGE_NAME}-${PACKAGE_VERSION}" MAKEFILE_ABS_PATH="${DKMS_SRC_DIR}/Makefile" MODULE_NAME="" # 【核心修复】:使用绝对路径去解析真正的 Makefile 提取驱动名 if [ -f "${MAKEFILE_ABS_PATH}" ]; then MODULE_NAME=$(sed -n -E 's/^DRIVER_NAME[[:space:]]*:?=[[:space:]]*([^[:space:]]+).*/\1/p' "${MAKEFILE_ABS_PATH}" | head -1 | sed 's/\.ko$//') fi # 如果从 Makefile 没解析出来,降级使用包名作为模块名 if [ -z "$MODULE_NAME" ]; then MODULE_NAME="${PACKAGE_NAME}" fi case "$1" in remove) echo "正在卸载 ${PACKAGE_NAME}..." # 1. 卸载内核模块 echo "检查内核模块状态: ${MODULE_NAME}" if lsmod | grep -q "^${MODULE_NAME}"; then echo "正在从当前内核中卸载模块 ${MODULE_NAME}..." if rmmod "${MODULE_NAME}" 2>/dev/null; then echo "模块 ${MODULE_NAME} 卸载成功" else echo "警告: 模块 ${MODULE_NAME} 卸载失败,可能有其他进程正在使用它" >&2 fi else echo "模块 ${MODULE_NAME} 当前未加载" fi # 2. 从 DKMS 移除模块 (修复:扩大 grep 范围以兼容 added/installed 各种状态) if dkms status | grep -q "${PACKAGE_NAME}/${PACKAGE_VERSION}"; then echo "从 DKMS 移除 ${PACKAGE_NAME} ${PACKAGE_VERSION}..." dkms remove -m "${PACKAGE_NAME}" -v "${PACKAGE_VERSION}" --all 2>/dev/null || true fi echo "正在强行清理 /lib/modules/ 下的所有 ${MODULE_NAME} 残留文件..." find /lib/modules/ -name "${MODULE_NAME}.ko*" -delete 2>/dev/null || true # 3. 更新模块依赖 echo "更新模块依赖..." depmod -a # 4. 删除开机自动加载配置 if [ -f "/etc/modules-load.d/${PACKAGE_NAME}.conf" ]; then echo "删除开机自动加载配置..." rm -f "/etc/modules-load.d/${PACKAGE_NAME}.conf" fi echo "${PACKAGE_NAME} 卸载完成" ;; upgrade) echo "软件包升级中,清理旧版本..." # 1. 升级时卸载旧版本的内核运行模块 if lsmod | grep -q "^${MODULE_NAME}"; then echo "正在卸载旧版本内核运行模块..." rmmod "${MODULE_NAME}" 2>/dev/null || true fi # 2. 从 DKMS 移除旧版本 if dkms status | grep -q "${PACKAGE_NAME}/${PACKAGE_VERSION}"; then echo "从 DKMS 移除旧版本模块记录..." dkms remove -m "${PACKAGE_NAME}" -v "${PACKAGE_VERSION}" --all || true fi # 3. 清理旧的内核模块文件 (原逻辑保留,提供兜底支持) rm -f /lib/modules/*/kernel/drivers/misc/${MODULE_NAME}.ko 2>/dev/null || true depmod -a ;; failed-upgrade) echo "升级失败,保留原有配置" ;; *) echo "prerm 被调用时参数: $1" >&2 ;; esac exit 0