☰
Ubuntu 18.04 磁盘爆满?彻底清理和卸载 snap 的完整指南
2026/10/15 9:21:07 网站建设 项目流程

1. 磁盘告警背后的真凶定位

1.1 从一次真实的磁盘爆满说起

某天下午,一台跑了两年多的 Ubuntu 18.04 开发机突然开始报警,根分区使用率直接飙到 100%。SSH 能连上,但任何写操作都失败,日志写不进去,服务一个接一个挂掉。第一反应是日志文件爆了,du -sh /*一跑,发现/var/lib/snapd这个目录占了大头,再往下钻,/var/lib/snapd/snaps里堆了几十个.snap文件,每个动辄几百 MB,加起来轻松吃掉十几 GB。

这就是 snap 在 Ubuntu 18.04 上的经典问题。Ubuntu 从 16.04 开始把 snap 作为默认的包管理方式之一,18.04 更是把不少系统组件都做成了 snap 包,比如core、gnome-3-26-1604、gtk-common-themes这些。问题在于,snap 的更新机制是保留旧版本 revision 的,默认保留最近 3 个版本(有些资料说 2 个,实测不同版本行为有差异),每次更新都会新增一个 revision 目录,旧的不会自动删。时间一长,磁盘就被这些"历史遗留"撑爆了。

1.2 snap 到底是个什么东西

在动手卸载之前,得先搞清楚 snap 是什么,不然容易误伤系统。snap 是 Canonical 主推的一种软件打包和分发格式,核心理念是"一个包搞定所有依赖",把应用和它需要的运行时库全部打包在一起,运行在沙箱环境里。好处是跨发行版、依赖隔离、自动更新;坏处也很明显——包体积大、启动慢、磁盘占用高、更新策略不透明。

你可以把 snap 理解成"自带干粮的旅行团":每个 snap 应用都自己带了一套锅碗瓢盆(依赖库),走到哪儿都能开火做饭,不用管当地厨房(系统库)长什么样。代价就是行李特别重,而且每来一批新游客(新版本),旧游客的行李还堆在仓库里不扔。

Ubuntu 18.04 上默认预装的 snap 相关组件包括:

组件作用是否可卸载
snapdsnap 后台守护进程可卸载,但需谨慎
coresnap 的基础运行时卸载 snapd 后自动清理
gnome-3-26-1604GNOME 运行时随 snapd 一起处理
gtk-common-themesGTK 主题资源随 snapd 一起处理
snap-store软件商店可单独卸载

1.3 为什么直接删文件不管用

很多人第一反应是rm -rf /var/lib/snapd/snaps/*,删完发现磁盘是空出来了,但过一会儿又满了,而且 snap 命令开始报错。原因在于 snapd 是个常驻服务,它维护着自己的状态数据库,你手动删文件,它不知道,下次更新或者重启时又会把东西拉回来,甚至因为状态不一致导致服务崩溃。

正确的思路是:要么用 snap 自己的命令清理旧版本,要么彻底把 snapd 卸掉。前者是"节流",后者是"断根"。下面两条路我都会讲清楚,你可以根据自己的需求选。

注意:卸载 snapd 之前,务必确认系统里没有正在依赖 snap 包的关键组件。Ubuntu 18.04 的桌面版有些应用(比如某些版本的 Chromium、Firefox)可能是 snap 装的,卸之前先snap list看一眼。

2. 先礼后兵:用 snap 命令清理旧版本

2.1 查看当前 snap 占用情况

动手之前先摸清家底。三条命令搞定:

# 查看所有已安装的 snap 包 snap list # 查看 snap 目录总占用 du -sh /var/lib/snapd/snaps # 查看每个 snap 的详细信息和 revision snap list --all

snap list --all会列出所有 revision,包括被禁用的旧版本。输出里Notes列显示disabled的就是旧版本,这些就是占空间的元凶。实测一台跑了半年的机器,gnome-3-26-1604能攒下 4 个 revision,每个 200MB 左右,光这一个就吃掉 800MB。

2.2 设置自动清理旧版本

snap 提供了一个配置项控制保留多少个旧 revision:

# 只保留最近 2 个 revision(默认通常是 3) sudo snap set system refresh.retain=2

这个值最小可以设到 2,不能再低了,设 1 会报错。设完之后,snapd 在下次自动更新时会按这个策略清理。但注意,这个设置只对之后的更新生效,已经堆积的旧版本不会自动删,得手动清一次。

2.3 手动批量清理 disabled 的旧版本

这是最实用的操作,一条命令搞定:

# 找出所有 disabled 的 snap 并逐个移除 snap list --all | awk '/disabled/{print $1, $3}' | \ while read snapname revision; do sudo snap remove "$snapname" --revision="$revision" done

拆解一下这条命令的逻辑:snap list --all输出所有包,awk过滤出含disabled的行,提取第一列(包名)和第三列(revision 号),然后循环调用snap remove指定 revision 删除。实测下来,这一条命令能从一台积攒了半年的机器上清出 5-8GB 空间。

实操心得:执行前先snap list --all | grep disabled | wc -l数一下有多少个待清理项,心里有数。清理过程中如果某个包正在被使用,会提示失败,跳过即可,不影响其他包。

2.4 清理后的验证

清完再跑一次du -sh /var/lib/snapd/snaps,对比一下前后的数字。如果空间释放不明显,可能是/var/lib/snapd/cache里还有缓存的下载包,这个目录也可以清:

sudo rm -rf /var/lib/snapd/cache/*

这个 cache 目录存的是下载中的 snap 包临时文件,正常情况下会自动清理,但异常中断时可能残留。删它没有风险,snapd 需要时会重新下载。

3. 彻底卸载 snapd 的完整流程

3.1 卸载前的依赖排查

如果你决定彻底跟 snap 说再见,第一步不是直接卸,而是排查依赖。跑这两条命令:

# 列出所有 snap 包 snap list # 检查是否有系统关键组件依赖 snap apt list --installed 2>/dev/null | grep -i snap

重点关注snapd、snap-confine、ubuntu-core-launcher这几个。如果snap list里有你正在用的应用(比如某些编辑器、浏览器),先想好替代方案——用 apt 装 deb 版本,或者换其他分发方式。

3.2 分步卸载 snapd

卸载顺序很重要,搞错了会留下残留。推荐流程:

# 第一步:先移除所有已安装的 snap 应用 # 逐个移除,或者用循环 for pkg in $(snap list | awk 'NR>1{print $1}'); do sudo snap remove "$pkg" done # 第二步:停止 snapd 服务 sudo systemctl stop snapd sudo systemctl disable snapd # 第三步:卸载 snapd 包 sudo apt purge snapd -y # 第四步:清理残留目录 sudo rm -rf /var/lib/snapd sudo rm -rf /var/cache/snapd sudo rm -rf ~/snap

apt purge比apt remove更彻底,会连配置文件一起删。~/snap是当前用户的 snap 数据目录,也要清掉,不然每个用户目录下都留一份。

3.3 阻止 snapd 被重新安装

Ubuntu 18.04 有个坑:卸载 snapd 之后,某些 apt 操作可能会把它作为依赖又装回来。比如你装某个包,它的推荐依赖里带了 snapd。解决办法是创建一个 apt 的偏好文件,把 snapd 钉死:

# 创建偏好文件 sudo tee /etc/apt/preferences.d/nosnap.pref << 'EOF' Package: snapd Pin: release a=* Pin-Priority: -10 EOF

Pin-Priority: -10表示负优先级,apt 永远不会主动安装这个包。这个技巧在 Debian 系里很通用,用来屏蔽任何你不想装的包。

3.4 卸载后的系统检查

卸完重启一次,然后检查:

# 确认 snapd 服务不存在 systemctl status snapd # 确认 snap 命令不存在 which snap # 确认目录已清理 ls /var/lib/snapd 2>/dev/null

如果systemctl status snapd报 "Unit snapd.service could not be found",说明卸干净了。which snap应该没有任何输出。这时候再df -h看一眼根分区,通常能释放出 10GB 以上的空间。

注意:卸载 snapd 后,Ubuntu 的软件商店(如果之前是 snap 版)会失效。桌面用户如果还需要图形化装软件,可以改用gnome-software的 apt 后端,或者直接用命令行 apt。

4. 卸载 snap 之后的替代方案

4.1 用 apt 装回必要的应用

snap 卸了,原来用 snap 装的应用得找替代。常见对应关系:

原 snap 应用apt 替代方案备注
chromiumapt install chromium-browser注意 18.04 上这个包可能又指向 snap,需加 PPA
firefoxapt install firefox官方 deb 版
code官方 deb 包手动安装从官网下 .deb
vlcapt install vlc直接可用
htopapt install htop直接可用

Chromium 在 Ubuntu 18.04 上是个特例,官方源里的chromium-browser后来被改成了 snap 的过渡包,装完实际还是 snap。要装真正的 deb 版,得加第三方 PPA 或者用其他方式。这也是很多人下决心卸载 snap 的导火索之一。

4.2 用 Flatpak 或 AppImage 作为补充

如果你确实需要 snap 那种"跨发行版、依赖隔离"的特性,可以考虑 Flatpak 或 AppImage。Flatpak 的磁盘管理比 snap 友好一些,flatpak uninstall --unused能清理不再需要的运行时。AppImage 更简单,单个文件,用完删掉就行,不留残留。

不过说实话,对于服务器场景,apt 足够了。服务器上跑的东西大多是命令行工具和服务,deb 包管理成熟稳定,没必要引入 snap 这层额外的复杂度。

4.3 服务器场景的极简建议

如果是服务器,我的建议是:装系统时就选 minimal 安装,或者装完立刻卸 snap。服务器不需要图形界面,snap 带来的那点"便利"完全抵不过它带来的磁盘和维护负担。一台干净的 Ubuntu 18.04 服务器,卸掉 snap 后根分区占用能控制在 2GB 以内,跑几年都不用担心磁盘问题。

5. 常见问题与排查实录

5.1 卸载 snapd 后 apt 报错

现象:apt update或apt install时报 "snapd 依赖问题"。

原因:某些包的依赖链里还有 snapd,purge 时没处理干净。

解决:

sudo apt --fix-broken install sudo apt autoremove

如果还不行,检查/etc/apt/preferences.d/nosnap.pref是否生效,然后sudo apt update刷新缓存。

5.2 snap 命令删不掉某个包

现象:snap remove xxx卡住或报 "snap is in use"。

原因:该 snap 的进程还在运行,或者有 mount 挂载点没释放。

解决:

# 查看相关进程 ps aux | grep snap # 强制终止 sudo pkill -f snap # 检查挂载点 mount | grep snap # 卸载挂载 sudo umount /snap/xxx/... # 再试删除 sudo snap remove xxx

实在删不掉,直接走彻底卸载流程,apt purge snapd会强制清理。

5.3 磁盘空间释放了但很快又满

现象:清理后空间回来,过几天又满了。

原因:snapd 自动更新又拉了一堆新 revision。

解决:要么设置refresh.retain=2并定期手动清,要么彻底卸载。治标不治本的话,可以写个 cron 任务每周跑一次清理脚本:

# 加到 crontab,每周日凌晨 3 点清理 0 3 * * 0 snap list --all | awk '/disabled/{print $1, $3}' | while read n r; do snap remove "$n" --revision="$r"; done

5.4 卸载后系统启动变慢或异常

现象:卸完 snapd 重启,启动时间变长或有报错。

原因:某些 systemd 单元还引用 snap 路径。

解决:

# 检查失败的单元 systemctl --failed # 检查 snap 相关的残留单元 ls /etc/systemd/system/ | grep snap ls /lib/systemd/system/ | grep snap # 手动禁用或删除残留单元 sudo systemctl disable <unit-name>

Ubuntu 18.04 上常见的是snapd.socket和snapd.seeded.service,purge 时一般会处理,但偶尔有残留。

5.5 常见问题速查表

问题排查命令解决方向
磁盘满du -sh /var/lib/snapd/*清旧 revision 或卸 snapd
snap 命令卡住ps aux | grep snap杀进程后重试
apt 依赖报错apt --fix-broken install修复依赖链
空间反复满snap list --all设 retain 或写 cron
启动异常systemctl --failed清理残留单元
包删不掉mount | grep snap先 umount 再删

6. 我踩过的坑和几条实在建议

第一次处理这个问题时,我图省事直接rm -rf /var/lib/snapd,结果 snapd 服务崩溃,系统日志刷屏,最后不得不重装。后来才明白,snapd 的状态管理是"数据库+文件"双轨的,手动删文件等于把数据库和实际文件搞不一致了,服务自然崩。

第二次我学乖了,先snap remove再apt purge,但忘了清~/snap,结果用户目录下留了一堆缓存,虽然不影响系统,但看着膈应。所以清理要彻底,系统目录和用户目录都得管。

还有一次是在一台生产服务器上操作,卸完 snapd 后没检查 systemd 单元,重启后发现snapd.socket还在尝试启动,虽然不影响业务,但日志里一直报错。后来加了systemctl mask snapd.socket才彻底安静。

几条实在建议:

  • 服务器装系统时直接选 minimal,从源头避免 snap 进来。
  • 桌面用户如果要用 snap,第一时间设refresh.retain=2,并养成每月清一次的习惯。
  • 卸载前一定先snap list,确认没有关键应用依赖。
  • 卸载后重启验证,别嫌麻烦,很多残留问题重启才暴露。
  • 保留一个 apt 偏好文件,防止 snapd 被依赖链偷偷装回来。

这套流程我在好几台机器上跑过,从 Ubuntu 18.04 到 20.04 都适用,20.04 之后 snap 的清理机制略有改进,但核心逻辑一样。磁盘告警这种事,预防比救火重要,与其等满了再手忙脚乱,不如装完系统就花五分钟把 snap 处理掉。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询