1. 为什么要动WSL:C盘爆掉的根源,以及为什么越早迁越省事
1.1 你是从这一步开始吃满C盘的
不少朋友第一次接触WSL,都是因为想在Windows里用Linux环境,于是照着教程敲了一行wsl --install -d ubuntu-24.04,装完发现一切正常,接下来就是装Docker、装CUDA、跑项目、拉镜像,日子过得很滋润。直到某天你打开资源管理器,发现C盘只剩几个G,才开始到处找空间到底被谁吃了。
这里有个很反直觉的事实:WSL真正占用C盘空间的,不是你“看得到”的Ubuntu系统目录,而是一个名叫ext4.vhdx的虚拟磁盘文件。它藏在类似C:\Users\你的用户名\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu24.04LTS_xxxx\LocalState\这种一串很长的路径下面,文件名就叫ext4.vhdx。
这个文件的特点是:你以为wsl --uninstall或者删了Ubuntu的App就能腾出几十个G,结果删完发现C盘空间纹丝不动——因为你根本没删到ext4.vhdx。另一个特点是它只增不减:你在WSL里装了多少东西,这个文件就膨胀到多大,哪怕你后来把里面的软件删了、日志清了,这个文件也几乎不会自动缩水。
所以移动WSL到其他磁盘,本质上就是在处理这个vhdx文件的“搬家”问题。这件事我建议越早做越好,因为当C盘已经爆红、WSL里积累了上百G数据的时候再迁,导出的文件会巨大,迁移耗时也会变得非常折磨人。
1.2 WSL2和WSL1的迁移区别
动手之前,你得先分清自己用的是WSL1还是WSL2,因为两者的迁移路径不完全一样。
WSL2基于轻量级虚拟机,所有文件都打包在ext4.vhdx里,这决定了它的“体量”非常庞大,但也意味着它可以整个打包导出、整体迁移,操作起来逻辑非常清晰。WSL1则没有vhdx文件,它是直接把Linux系统调用翻译给Windows内核处理,文件目录直接映射到Windows文件系统里,所以迁移WSL1更像是在搬文件夹。
通过wsl -l -v命令可以查看当前发行版的版本号,如果VERSION列显示2,就是WSL2。目前新安装的基本都是WSL2,网上那些“WSL占空间”“WSL怎么迁移”的求助帖,十有八九都是在跟ext4.vhdx搏斗。
1.3 迁移的整体逻辑:不是“剪切”而是“导出—注销—导入”
很多人第一次迁移WSL时,下意识的想法是“我能不能直接把那个包的目录剪切到D盘”。我劝你别这么做,因为Windows Store版WSL的注册信息跟安装目录是绑定的,你光把文件夹挪走,系统根本认不出这个发行版,反而会把启动器搞坏。
正确思路是三个命令的组合:wsl --export导出、wsl --unregister注销、wsl --import导入。可以理解为把整个Linux系统打包成一个tar或vhdx文件,搬个家,再重新注册。这套逻辑适用于所有基于WSL的发行版,不只Ubuntu,Debian、Fedora、openSUSE都一样。
后面我会把每一条命令的参数、坑点、以及执行后你可能会遇到的意外状况逐一展开讲。先在这里留一句最重要的提醒:wsl --unregister会彻底删除当前发行版的所有数据,这一步一旦敲下去,后悔药都不一定有。所以顺序绝对不能错——先导出备份,再注销,最后导入。
2. 迁移前体检:确认版本、备份数据、规划新位置
2.1 把当前Windows和WSL的家底摸清楚
开始迁移前,先花两分钟做一次体检,别急着敲命令。打开PowerShell或Windows Terminal,依次执行下面几条命令:
# 查看WSL版本信息 wsl --version # 列出所有已安装的发行版及其状态 wsl -l -v # 查看当前WSL发行版默认用户、系统信息 wsl -d Ubuntu-24.04 whoamiwsl --version在较新的WSL版本里会显示WSL内核版本、WSLg版本、默认WSL版本等信息。如果提示wsl: 命令未找到,说明你的系统还没启用WSL,或者是旧版Windows 10上的半残状态,建议先把wsl --update跑到最新再继续。
wsl -l -v会列出你装过的所有发行版,比如Ubuntu-24.04、Ubuntu-22.04、Debian等。注意看NAME列,后面--export和--unregister用的发行版名称必须跟这里一字不差,大小写也要对上。建议直接右键复制,不要手打。
wsl -d Ubuntu-24.04 whoami是为了确认当前WSL能否正常进入、默认用户是什么。如果这里就报错,先修好再迁移,别带着病搬家。
2.2 备份不是走过场:先导出到D盘再动手
我见过太多人在网上看到迁移教程,觉得“我里面没什么重要数据”,跳过导出直接--unregister,然后第二天想起来有个项目代码在WSL里没提交,整个人就傻了。哪怕你觉得自己数据不重要,我也强烈建议至少导出一次,因为导出这个动作本身不花几分钟,但万一出问题,它就是你的救命稻草。
在Windows的PowerShell里执行:
# 建议先创建一个专门的备份目录 mkdir D:\wsl-backup # 将Ubuntu-24.04完整导出到tar文件 wsl --export Ubuntu-24.04 D:\wsl-backup\ubuntu-24.04-backup.tar导出时间取决于你的ext4.vhdx有多大。几个G的系统通常只要一两分钟,如果里面装了Docker镜像、CUDA、大型依赖库,可能得等上十几分钟。导出过程中PowerShell窗口会一直处于“卡住”状态,中间没有任何进度条,这是正常现象,别急着按Ctrl+C。
导出完成后,查看一下tar文件的大小,再对比一下C盘里ext4.vhdx的大小。正常情况下两者应该比较接近,如果tar比vhdx小很多,别慌,这是因为tar归档不会保留虚拟磁盘的空闲空间。比如一个20G的vhdx里实际只装了几个G的东西,tar可能只有五六G。
2.3 目标目录怎么定:C盘之外的选择
备份完成后,接下来要规划新位置。很多人随手建一个D:\WSL就开始导入了,事实证明这样后续管理起来特别乱。我个人的习惯是按照“盘符→目录→发行版”的三级结构来安排,比如:
D:\WSL\Ubuntu-24.04\ D:\WSL\Ubuntu-22.04\ D:\WSL\Debian\每个发行版一个独立文件夹,好处是以后你想迁移其中某一个、或者想单独备份某一个发行版时,不会互相干扰。目标目录建议不要放在C盘,否则等于白折腾。如果你有机械硬盘和固态硬盘,优先选固态硬盘那块,因为WSL日常跑编译、跑容器时对磁盘IO很敏感,放在机械盘上你会感受到什么叫“整个世界都慢了下来”。
目标目录路径中不要带空格、不要带中文,理由跟你写代码时不喜欢路径带空格一样——某些工具、脚本处理这种路径时会莫名其妙报错,到时候排查成本远高于你找一个干净目录的成本。
2.4 关闭正在运行的WSL
迁移前还有个容易被忽略的步骤:先让WSL彻底关机。
# 强制关闭所有WSL实例 wsl --shutdown这条命令会停止后台所有WSL发行版,包括Docker Desktop依赖的那些。如果不执行这一步,WSL的ext4.vhdx文件处于“被占用”状态,导出时可能因为文件被锁定导致导出出来的tar不完整,或者导入后文件系统有问题。
执行完wsl --shutdown后,最好再确认一下没有WSL相关进程还在跑。可以用tasklist | findstr -i wsl看看,如果有进程残留,等几秒再试,或者干脆重启一次系统,养成“迁移前先重启一遍”的好习惯,能避开很多奇怪的坑。
3. 正式迁移:export、unregister、import三步走
3.1 导出整个发行版到tar文件
在上一节我们已经做过一次导出,那其实已经算正式迁移的第一步了。如果你在2.2节已经执行过导出,而且你的WSL环境在这之后没有再动过,那可以直接跳过这次导出,用之前的tar文件就行。但为了稳妥,我会在迁移前再重新导出一次,确保tar文件是最新状态。
wsl --export Ubuntu-24.04 D:\wsl-backup\ubuntu-24.04-backup.tar命令格式不复杂,--export后面跟发行版名称,再跟目标tar文件路径。导出完成后可以顺便用PowerShell查看文件大小确认没有异常:
Get-Item D:\wsl-backup\ubuntu-24.04-backup.tar | Select-Object Length, LastWriteTime这一步的重点是:确认tar文件存在,且大小不为0。我知道这是废话,但真的有人导出失败还继续往下走,最后才来找我说导入失败,检查发现原来tar文件根本就没生成。另外注意,wsl --export在WSL较新版本中还能导出为vhdx格式,加一个--vhd参数就行。但我更推荐导出成tar,因为它的兼容性更好,之后导入时WSL会自动生成新的vhdx文件。
3.2 注销旧实例:清掉C盘空间的关键一步
导出完成后,接下来的操作会让人有点紧张,但逻辑上必须这么做。
wsl --unregister Ubuntu-24.04执行这条命令后,WSL会删除这个发行版的注册信息和所有数据文件,包括C盘里的ext4.vhdx。C盘被占用的那几十个G,在这一步之后就会被释放出来。如果这一步做完你发现C盘空间没有变化,别怀疑,去检查一下C:\Users\你的用户名\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu24.04LTS_*\LocalState\下的ext4.vhdx是否还存在,如果存在,说明你注销的发行版名称可能跟实际名称不一致,命令没匹配上。
执行完--unregister后,如果你在步骤2.2没有做备份,那你现在已经没有后悔药可以吃了。所以再次强调顺序,请确保2.2或者3.1的导出都完成了,再敲这条命令。
注销之后,你会发现开始菜单里原来多出来的Ubuntu图标变成了“不可用”状态,或者点击后提示“没有已安装的发行版”,这些都属于正常现象,不要慌,导入完成后一切都会恢复。
3.3 导入到新盘:--import的坑要提前避
注销成功后,接下来就是把刚才导出的tar文件导入到新位置。
# 先在D盘创建目标目录 mkdir D:\WSL\Ubuntu-24.04 # 导入发行版 wsl --import Ubuntu-24.04 D:\WSL\Ubuntu-24.04 D:\wsl-backup\ubuntu-24.04-backup.tar --version 2--import参数格式是:发行版名称、目标安装目录、tar文件路径。注意--version 2必须显式指定,确保导入后仍然是WSL2,否则在某些旧版本WSL里可能会莫名其妙变成WSL1。
这一步踩坑概率极高,新手常遇到的报错包括:
- “文件名、目录名或卷标语法不正确”:多半是路径里有中文或空格,或者目标目录没有提前创建。先执行
mkdir确保目录存在。 - “进程退出代码非零”:常见原因是tar文件损坏,或者目标磁盘空间不足。检查磁盘空间和tar文件完整性。
- “请求的操作系统不是所需操作系统版本”:通常是WSL版本太旧,先跑
wsl --update升级到最新版本。
导入完成后,系统会自动在D:\WSL\Ubuntu-24.04\下生成一个ext4.vhdx文件,这就是你的Ubuntu新家了。此时可以验证一下:
wsl -l -v wsl -d Ubuntu-24.04 lsb_release -a如果一切正常,你会看到Ubuntu-24.04的VERSION显示为2,并且lsb_release能正常输出系统版本信息。
3.4 导入后第一件事:确认默认用户并修复
这里有个几乎每个人都会撞上的坑:用wsl --import导入的发行版,默认用户会变成root,而不是你之前用的那个普通用户。这意味着,你在WSL里执行sudo可能会被提示不需要密码,但你的/home/你的用户名目录、你的shell配置、你的SSH密钥等全都变成了“另一个用户”的视角,Windows Terminal里打开Ubuntu标签页也直接以root身份进入。
修复方法很简单,进入发行版内部,修改/etc/wsl.conf:
# 以root身份进入WSL wsl -d Ubuntu-24.04 -u root # 编辑wsl.conf文件 vim /etc/wsl.conf如果wsl.conf不存在,就新建一个。写入以下内容:
[user] default=你的用户名保存退出后,在Windows PowerShell里执行以下命令,让WSL重新加载配置:
wsl --shutdown wsl -d Ubuntu-24.04这时你就会以普通用户身份登录了,/home/你的用户名目录下的文件、权限、配置也都恢复正常视角。如果你忘了原来的用户名是什么,可以先用root身份跑ls /home/看一眼有哪些目录,再把用户名填进去。
4. 迁移后的善后工作:验证、清理、恢复体验
4.1 确认ext4.vhdx真的搬到了新盘
导入完成后,很多人会习惯性打开资源管理器看一眼C盘空间,发现确实释放了几十个G,就以为大功告成了。但我建议再做一步更严格的验证:确认新生成的ext4.vhdx确实在D盘,而且C盘那个旧目录已经不存在。
用资源管理器直接导航到D:\WSL\Ubuntu-24.04\,看是否有ext4.vhdx文件。同时检查C:\Users\你的用户名\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu24.04LTS_*\LocalState\下的ext4.vhdx是否已经被清除。如果旧的还在,可能是注销不彻底,也可能是残留垃圾,可以手动删掉,但前提是你已经确认新位置的WSL可以正常运行。
然后进WSL里再验证一下,比如运行比较耗磁盘IO的命令,或者直接在你的项目里跑一遍测试,确保文件系统一切正常。我自己会在迁移后做一次sudo apt update,如果软件源能正常拉取、磁盘读写不报错,基本就说明基础环境没问题了。
4.2 删除导出包,顺便给D盘腾个地方
迁移成功后,最早在2.2节导出的那个tar备份文件就可以考虑删掉了。一个动辄几个G甚至十几个G的大文件放在那里,只会白白占用磁盘空间。
但删除之前,我建议你在D盘保留它至少一天,等确认新WSL环境稳定运行后,再把它清掉。如果真的在导入后发现问题,可以直接用这个tar再走一遍导入流程,总比重新配置一遍环境强。
如果你连这个tar文件都懒得保留,那至少要确保你的代码仓库、文档、重要配置都已经提交到远程仓库或者复制到Windows侧。WSL的ext4.vhdx一旦损坏,恢复难度非常大,不要指望“数据应该还在”这种心理安慰。
删除导出包的PowerShell命令:
Remove-Item D:\wsl-backup\ubuntu-24.04-backup.tar4.3 多发行版环境下的迁移注意事项
如果你装了不止一个发行版,比如Ubuntu-24.04和Ubuntu-22.04并存,迁移时一定要逐个操作,不要一次性把所有发行版都注销。道理很简单,万一手误打错命令、或者其中一个发行版的导出文件有问题,至少你还能用另一个发行版继续干活。
操作顺序上,先迁移你最依赖的那个发行版,确认没问题后再迁移下一个。另外,虚拟机内部的网络状态、Docker Desktop是否还在运行、其他依赖特定WSL发行版的应用,都需要在迁移前先关闭。Docker Desktop特别容易出现“绑定发行版失败”的情况,如果迁移后发现Docker Desktop起不来,先到它的设置里重新配置WSL集成。
还有就是,如果你用wsl --set-default设置过默认发行版,迁移后建议重新执行一次,把默认发行版指到你迁移后的目标上。命令是:
wsl --set-default Ubuntu-24.04不让这些注册状态“悬空”,才能减少以后许多莫名其妙的问题。
5. 延伸与避坑:vhdx瘦身、空间不释放、常见报错合集
5.1 删了文件但C盘空间没回来?那是vhdx在骗你
这个场景在WSL用户群里特别常见:明明在WSL里删除了几十G的文件,回到Windows一看,C盘可用空间几乎没变化。原因我在开头已经提过——ext4.vhdx是动态增长但不会自动收缩的虚拟磁盘。你删除文件释放的只是虚拟磁盘内部的空闲空间,而不是Windows视角下的物理空间。
WSL的vhdx文件默认是动态扩展的,你装了多少数据它就增长到多大,当你删掉数据时,它并不会自动把那些空闲的块“还给”Windows。这个行为很像虚拟机里的磁盘,你在虚拟系统里删了文件,宿主机上的磁盘镜像文件大小也不会自动变小。
理解了这个原理,你就能明白为什么有时候C盘空间看着那么紧张,因为WSL这个“胃口”只会涨不会自动缩。不过好在有办法解决,看下一节。
5.2 用diskpart给vhdx瘦身
如果你已经完成了迁移,但希望把新位置D:\WSL\Ubuntu-24.04\ext4.vhdx里的空闲空间释放掉,或者你之前已经迁移过、现在觉得这个文件太大,可以用Windows自带的diskpart工具来压缩。
先执行wsl --shutdown关闭WSL,确保vhdx没有被占用。然后打开PowerShell,进入diskpart:
diskpart # 在diskpart里执行 select vdisk file="D:\WSL\Ubuntu-24.04\ext4.vhdx" # 只读挂载该虚拟磁盘 attach vdisk readonly # 压缩虚拟磁盘 compact vdisk # 卸载虚拟磁盘 detach vdisk # 退出diskpart exit压缩所需时间取决于vhdx的大小和当前磁盘IO情况,几十G的vhdx可能要几分钟。压缩完成后,你会发现vhdx文件明显变小了。
如果提示“虚拟磁盘当前被使用”或者“拒绝访问”,说明wsl --shutdown之后还有进程占用,可以先用tasklist | findstr -i wsl检查残留进程,或者干脆重启一次再执行。
另外,WSL较新版本(0.70及以上)提供了更简单的命令:
wsl --manage Ubuntu-24.04 --set-sparse true开启稀疏虚拟磁盘后,vhdx文件会在内部空闲块被释放时自动归还空间,相当于给磁盘开了“自动瘦身”模式。这个功能我只建议在较新WSL版本上尝试,老版本没有这个参数就别硬试了,老实走diskpart路线。
5.3 迁移过程中常见的几个报错与解法
迁移WSL的过程中,我遇到过不少报错,网上也看到很多求助帖,这里整理一份高频问题对照表,以后你遇到类似情况可以直接对照排查。
| 报错信息 | 常见原因 | 解决方法 |
|---|---|---|
| 文件名、目录名或卷标语法不正确 | 路径含空格、中文,或目标目录未创建 | 用纯英文路径,先mkdir再导入 |
| 进程退出代码非零 | tar文件损坏、磁盘空间不足 | 检查导出文件完整性,清理磁盘空间 |
| 请求的操作系统不是所需操作系统版本 | WSL内核/组件版本过旧 | 执行wsl --update升级到最新版本 |
| 找不到指定的文件 | 发行版名称拼写错误 | 用wsl -l -v对照名称,直接复制 |
| 导入后默认用户是root | wsl --import会重置默认用户 | 修改/etc/wsl.conf配置default用户 |
| 导入后wsl -l -v显示空白或者无法启动 | vhdx文件损坏,或导入前未wsl --shutdown | 先用备份tar重新导入,不行就重装WSL |
| 迁移后Docker Desktop无法使用 | Docker Desktop绑定了旧发行版名称 | 在Docker Desktop设置里重新开启WSL集成 |
其中“导入后默认用户是root”和“迁移后Docker Desktop无法使用”是最容易被忽视的,很多人导入成功后兴奋地去跑Docker,结果发现权限全乱套,还以为自己迁移坏了。其实只要顺着上面表格里的思路排查,大部分问题都能快速定位。
另外有个经验分享:如果你发现迁移后WSL里的/etc/wsl.conf内容总是被重置,或者某些系统级配置没有生效,多半是WSL缓存了旧配置。执行wsl --shutdown后再进一次,WSL会重新读取配置文件。如果还不行,检查配置文件里有没有语法错误,用wsl -d Ubuntu-24.04 -u root以root身份进去修改,权限不对也会导致写入失败。
我见过不少人迁移完WSL以后,觉得“既然硬盘空间还够,就先不管了”,结果过了一两个月C盘又爆了,再回头看D盘那个vhdx已经膨胀到几十个G。所以我的习惯是:迁移后隔一段时间就用diskpart给vhdx做一次瘦身,或者直接开启sparse模式一劳永逸。你如果也想省心,不妨把“定期检查vhdx大小”写进你的系统维护计划里,至少比每次等到C盘爆红再临时抱佛脚要舒服得多。