☰
Ubuntu 18.04 磁盘爆满?彻底卸载 snap 释放空间实战
2026/10/14 5:46:04 网站建设 项目流程

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

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

事情的起因很朴素:一台跑了两年多的 Ubuntu 18.04 开发机突然开始报磁盘空间不足,df -h一看根分区使用率 100%,连apt都装不了东西。第一反应是日志文件堆积,du -sh /var/log/*扫了一遍,才 2 个 G 不到;再查/home、/tmp、Docker 目录,都不是大头。最后用du -sh /* 2>/dev/null | sort -rh | head -20逐层往下钻,才把目标锁定在/var/lib/snapd这个目录上——它一个人吃掉了将近 40 个 G。

如果你也遇到过类似场景,标题里说的“snap 占用 100%”大概率不是指 CPU 占用,而是磁盘空间被 snap 相关目录吃满。这是 Ubuntu 18.04 上非常典型的一类问题,尤其是那些长期运行、装过不少 snap 包的机器。snap 这套包管理机制从设计上就偏向“多版本共存 + 只增不减”,默认保留每个应用的历史修订版本,时间一长,磁盘就被悄悄蚕食。

这篇文章面向的是手里有 Ubuntu 18.04(或相近版本)机器、被 snap 占用磁盘困扰、想彻底卸载 snap 换回传统 apt 管理的运维和开发者。我会把“为什么 snap 会膨胀”“怎么安全地卸载 snap”“卸载后有哪些坑”这几件事讲透,给出可以直接抄作业的命令,也会分享我自己踩过的几个坑。哪怕你只是想知道 snap 到底该不该留,看完也能有个判断。

1.2 snap 为什么会把磁盘吃满

要理解这个问题,得先搞清楚 snap 的存储模型。snap 包不是像 deb 那样把文件散落到系统各个目录,而是每个应用打包成一个自包含的 squashfs 镜像,挂载到/snap/<应用名>/<修订号>下。关键在于这个“修订号”:每次应用更新,snapd 会下载一个全新的修订版本,而不是覆盖旧的。默认情况下,系统会保留至少 2 个、最多 3 个历史修订版本,方便你随时回滚。

听起来很贴心,但代价是磁盘。一个稍微大点的应用,比如某个 IDE 或者浏览器,单个修订版本可能就有几百兆到 1G 多。保留三个版本,就是三倍空间。更麻烦的是,/var/lib/snapd/snaps里存的是这些修订版本的原始.snap文件,/snap下挂载的又是解压后的内容,两边加起来占用更可观。再加上/var/lib/snapd/cache里的下载缓存,如果清理机制没正常触发,缓存也会越堆越多。

还有一个容易被忽略的点:snap 的自动更新和清理是异步的。有时候更新下载完了,旧版本却因为某些原因(比如应用正在运行、或者 snapd 服务异常)没有被及时清理,就一直挂在那里。我见过最夸张的一台机器,某个应用攒了七八个历史修订,光这一个应用就占了十几个 G。所以“snap 占用 100%”本质上是这套“只增不减”的存储策略在长期运行下的必然结果,不是 bug,是设计取舍。

2. 卸载前的评估与准备工作

2.1 先搞清楚到底装了哪些 snap 包

动手卸载之前,千万别上来就apt remove snapd。你得先摸清楚现状:系统里到底装了哪些 snap 包,哪些是系统关键组件,哪些是你自己装的。因为 Ubuntu 18.04 的某些核心组件(比如core、snapd本身,甚至某些版本的gnome相关包)是以 snap 形式存在的,盲目全删可能把桌面环境搞崩。

第一步,列出所有已安装的 snap 包:

snap list --all

这个命令会列出所有包及其所有修订版本,输出里会看到类似core18、gnome-3-28-1804、gtk-common-themes这种看起来像系统依赖的包,也会有你手动装的code、chromium之类。重点关注两列:Name和Rev,以及Notes列里的disabled标记——被标记为 disabled 的就是旧版本,是可以优先清理的对象。

第二步,看看每个包占了多少空间。snap 没有直接给出体积的命令,但可以手动算:

du -sh /var/lib/snapd/snaps/*.snap | sort -rh | head -20

这一步能让你直观看到哪个包是大头。通常排在前面的都是浏览器、IDE、运行时环境这类体积大的应用。

2.2 判断哪些包可以安全移除

列完清单后,要做一个关键判断:这个系统到底还需不需要 snap。如果你的机器是纯命令行服务器,snap 上装的东西你根本没用过,那可以放心大胆地全卸。但如果是带桌面的工作站,就要小心了,因为 Ubuntu 18.04 的软件中心(Ubuntu Software)本身就是个 snap 应用,某些 GNOME 扩展和主题也是 snap 形式。

我的经验判断法是:先看snap list里有没有你主动安装并正在使用的应用。如果没有,或者这些应用都能用 apt 或官方 deb 包替代,那就走“彻底卸载 snap”的路线。如果有那么一两个非用不可的 snap 应用,那就退而求其次,只做“清理旧版本 + 限制保留数量”,而不是全卸。

这里有个实操心得:先记录,再动手。把snap list --all的完整输出重定向到一个文件里存着,比如snap list --all > ~/snap-backup.txt。万一卸载后发现有东西依赖 snap,你还能对照着知道原来装了什么,方便恢复。这个习惯帮我省过好几次事。

注意:卸载 snapd 之前,务必确认你的系统没有把 snap 作为关键路径。比如某些云厂商的镜像里,监控 agent 或初始化脚本可能是 snap 装的,删了会导致实例异常。不确定的话,先在测试机上跑一遍完整流程。

3. 彻底卸载 snap 的完整实操

3.1 分步卸载所有 snap 应用

彻底卸载 snap 的正确顺序是:先删应用,再删 snapd 本体,最后清理残留目录。顺序错了会留下各种挂载点和残留文件,清理起来更麻烦。

第一步,移除所有手动安装的 snap 应用。可以写个循环批量处理:

for pkg in $(snap list | awk 'NR>1 {print $1}'); do sudo snap remove --purge "$pkg" done

这里--purge参数很关键,它会连同应用的用户数据和配置一起删除。如果你还想保留某些应用的数据,就去掉这个参数,但那样会留下~/snap下的数据目录,需要手动清理。注意core、snapd这类系统包可能删不掉或者删了会自动重装,没关系,下一步统一处理。

第二步,停止并禁用 snapd 服务,防止它在卸载过程中又自动拉起:

sudo systemctl stop snapd.service snapd.socket snapd.seeded.service sudo systemctl disable snapd.service snapd.socket snapd.seeded.service

第三步,卸载 snapd 本体:

sudo apt-get remove --purge snapd -y sudo apt-get autoremove --purge -y

到这一步,snap 的运行时基本就没了。但别急,磁盘空间还没真正释放,因为残留目录还在。

3.2 清理残留目录与挂载点

这是最容易出问题的一步。snap 会在好几个地方留下痕迹,得逐个清理:

sudo rm -rf /var/cache/snapd/ sudo rm -rf /var/lib/snapd/ sudo rm -rf /snap sudo rm -rf /var/snap rm -rf ~/snap

/var/lib/snapd是重灾区,里面snaps子目录存着所有.snap文件,cache存着下载缓存,删掉它才能真正释放那几十个 G。/snap是挂载点目录,卸载 snapd 后可能还残留一些空的挂载目录,一并删掉。

删完之后,检查一下有没有残留的挂载:

mount | grep snap

如果还有输出,说明有 squashfs 镜像还挂着,用sudo umount <挂载点>逐个卸载,再删目录。我遇到过一种情况:某个 snap 应用进程没退干净,导致挂载点 busy 删不掉,这时候sudo fuser -km /snap/<应用名>把占用进程杀掉再删就行。

最后,为了防止 apt 在后续更新时又把 snapd 装回来,需要加一个屏蔽规则:

sudo tee /etc/apt/preferences.d/nosnap.pref > /dev/null <<'EOF' Package: snapd Pin: release a=* Pin-Priority: -10 EOF

这个 pin 优先级设为 -10,意思是“永远不要安装 snapd”,比任何仓库的优先级都低。这样即使某个包的依赖里带了 snapd,apt 也会拒绝安装,避免它偷偷回来。

3.3 验证卸载结果与空间回收

清理完,用几条命令验证一下成果:

df -h / snap list which snap

df -h /应该能看到根分区使用率明显下降,具体降多少取决于你之前攒了多少。snap list应该报 command not found,which snap也找不到,说明卸载干净了。

如果snap list还能执行,说明 snapd 没删干净,回去检查是不是有残留的包或者 PATH 里还有 snap 的软链接。另外,/etc/apt/sources.list.d/下可能有 snap 相关的源文件,虽然不影响使用,但为了干净也可以删掉。

提示:空间回收后如果df显示的数字和预期对不上,别慌。有时候被删除的文件还被某个进程持有句柄,空间不会立即释放。用sudo lsof | grep deleted | grep snap查一下,重启相关进程或直接重启机器就能释放。

4. 卸载后的常见问题与排查

4.1 桌面环境或应用异常怎么办

卸载 snap 后最常见的问题,是某些原本依赖 snap 的应用启动不了。比如你之前用 snap 装的浏览器、编辑器,卸载后图标还在但点开没反应。这不是系统坏了,只是那些应用本身没了,需要重新用 apt 或官方 deb 包安装。

还有一种情况更隐蔽:某些 GNOME 主题或扩展是 snap 形式,卸载后桌面外观变了或者扩展失效。这时候去“优化”工具里重新配置一下,或者用 apt 装对应的gnome-shell-extensions包即可。我自己的做法是,卸载前先把这些依赖关系理清楚,能换成 apt 版本的就提前换好,再动手卸 snap,避免中途桌面崩掉影响操作。

如果卸载后系统启动异常,进不了图形界面,别急。按Ctrl+Alt+F3切到 TTY,用命令行登录,检查systemctl status看哪个服务 failed,大概率是某个依赖 snap 的服务没起来。把对应服务禁用或换成非 snap 版本,再重启即可。

4.2 常见问题速查表

下面这张表整理了我实际处理这类问题时最常遇到的几种情况,以及对应的排查思路,方便你对照着快速定位:

现象可能原因排查与解决
df显示空间没释放文件被进程持有句柄lsof | grep deleted,重启相关进程或机器
snap list仍可执行snapd 未删干净检查dpkg -l | grep snap,重新 purge
应用图标点击无反应应用本身是 snap 装的用 apt 或 deb 重新安装该应用
桌面主题/扩展失效依赖 snap 形式的主题包安装 apt 版gnome-shell-extensions
apt 更新时 snapd 被装回缺少 pin 屏蔽规则添加/etc/apt/preferences.d/nosnap.pref
/snap目录删不掉挂载点 busyfuser -km杀进程后 umount 再删

4.3 几个我踩过的坑和独家技巧

第一个坑:别在 snap 应用运行时卸载。我有一次在浏览器还开着的时候执行卸载,结果/snap挂载点一直 busy,删目录报错,最后不得不重启才清理干净。正确做法是先关掉所有 snap 应用,或者干脆在单用户模式下操作。

第二个坑:~/snap目录容易被遗忘。这个目录在每个用户的家目录下,存的是 snap 应用的用户数据。系统级的/var/lib/snapd删了,但~/snap还在,尤其是多用户机器上,每个用户都有一份。清理时记得rm -rf ~/snap,或者遍历所有家目录处理。

第三个技巧:如果你只是想限制 snap 占用而不是彻底卸载,可以调整保留版本数:

sudo snap set system refresh.retain=2

这个值最小是 2,设成 2 能让 snapd 只保留当前版本和上一个版本,比默认的 3 省一些空间。但治标不治本,长期看还是卸载更彻底。

第四个技巧:卸载前用snap saved看看有没有保存的快照,如果有重要数据,先snap restore恢复出来再卸。这个命令很多人不知道,但关键时刻能救数据。

5. 卸载 snap 之后的管理策略

5.1 用 apt 替代 snap 的实践建议

彻底告别 snap 后,日常软件管理就回到 apt 和官方 deb 包的轨道上。大部分常用软件都有 apt 版本或者官方维护的 deb 仓库,比如浏览器、编辑器、开发工具等。我的建议是优先用发行版官方仓库,其次用软件官方提供的 deb 源,最后才考虑第三方 PPA。这样升级链路清晰,出问题也好排查。

对于确实只有 snap 版本、没有 deb 替代的软件,可以考虑用 Flatpak 或者 AppImage 作为备选。Flatpak 的存储模型比 snap 克制一些,支持清理未使用的运行时;AppImage 则是单文件,用完即删,不占系统目录。不过这些方案各有取舍,不是本文重点,知道有这么个退路就行。

5.2 长期维护的几点经验

卸载 snap 不是一劳永逸的事,后续维护有几个点要注意。一是定期检查df -h,养成看磁盘的习惯,别等爆满了才处理。二是 apt 更新时留意有没有包试图把 snapd 拉回来,虽然加了 pin 规则,但偶尔还是会有漏网的,看到就手动拒绝。三是如果系统里有自动化脚本或配置管理工具,记得把 snap 相关的任务清理掉,避免它们执行时报错。

我个人在实际操作中的体会是,snap 这套机制适合那些追求“开箱即用、自动更新”的桌面用户,但对磁盘敏感、追求可控性的服务器和开发机来说,传统 apt 管理更省心。卸载 snap 这个动作本身不复杂,难的是卸载前后的评估和清理,把这两头做扎实,整个过程就很稳。最后再分享一个小技巧:如果你有多台机器要处理,可以把上面这套流程写成一个 shell 脚本,加上前置检查(确认没有关键 snap 依赖)和后置验证(确认空间释放),批量执行效率高很多,也不容易漏步骤。

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

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

立即咨询