你在一台机器上卸载了一批存储相关的软件包,以为"卸干净了"。结果去翻目录,那些软件留下的配置目录还赫然在目。你以为是卸载失败了,重新卸一遍,它们还是不走。
现象
执行卸载(apt remove、apt purge、dnf remove)后:
- 软件留下的配置目录依然存在,里面还残留着配置文件或子目录;
- 有时内存里那个模块还加载着,下次开机也还会加载;
- 你以为"卸载了",实际系统里还留着一堆痕迹。
根因
原因在于包管理器删除目录的规则:它只删"空目录",非空目录不删。
当包管理器要移除一个属于该包的配置目录时,如果那个目录里还有内容(比如你后来自己放进去的文件、运行期生成的状态文件、或者别的包也往这里写过东西),包管理器会跳过删除——因为它不敢替你判断"这些剩余文件是不是别的东西在用的"。于是目录连同里面的残留就留了下来。
所以"卸了包,配置目录还在"是常态,不是异常。这不代表卸载失败,而是"包管理器按规则保留了一个非空目录"。
另外,配置文件本身也有讲究:remove(Debian 系)通常保留配置文件,purge 才会连配置一起删。如果你用的是 remove,那配置文件被保留是设计如此。
还有内核模块这一层:即使文件被删了,已经加载进内存的模块不会自动卸载,它一直生效到下次重启或手动卸载。
解决
手动把这几个层面清干净,注意顺序和确认。
第一步(务必先做):确认主程序不依赖这些包。
卸载前先看清楚:还有没有别的东西依赖这些包?
# Debian/Ubuntu:看谁依赖它
apt-cache rdepends <包名>
# 或整体检查是否有损坏的依赖
apt -f install
别把系统底座的东西误删了——有些存储模块可能是根文件系统、日志、或平台自身依赖的。确认安全再动手。
第二步:删残留目录。
# 看清楚里面有什么,别直接 rm -rf
ls -la /etc/<残留目录> /var/lib/<残留目录>
# 确认无用后删除
sudo rm -rf /etc/<残留目录>
第三步:删模块配置文件(阻止它下次开机加载)。
# 看哪些模块配置指向它
ls /etc/modules-load.d/ /etc/modprobe.d/
# 删除对应的配置文件
sudo rm /etc/modules-load.d/<相关配置>.conf
第四步:手动卸载内存里还加载着的模块。
# 看模块是不是还在
lsmod | grep <模块名>
# 卸载它(如果没人用)
sudo modprobe -r <模块名>
如果 modprobe -r 报"设备忙",说明还有东西在用,得先停掉相关服务再卸。
改完可以重启一次,确认开机不再加载,残留也没了。
延伸与预防
这条坑的教训是:"卸载包"和"清空痕迹"是两件事。 包管理器负责它自己那部分(它能确认属于该包的、且为空的目录),剩下的边角料需要你判断。
养成三个习惯:
- 清理前先确认依赖(
rdepends、apt -f install),别误伤系统底座; - 删目录前先
ls看清楚内容,别对不认识的目录rm -rf; - 记住"三层残留"这个概念:磁盘上的文件/目录、包管理器保留的配置文件、以及内存里已加载的模块。清干净要三层都照顾到,只删文件是不够的。
顺带一提,Debian 系里想"卸得干净一点",可以用 purge 代替 remove,它会连配置文件一起删——但这也意味着你的自定义配置会一并消失,升级/重装时得重新配。所以到底用哪个,取决于你是"临时移除、以后还装回来"还是"彻底不要了"。