
1. 迁移之前先想清楚你要搬的到底是什么很多人一听「WSL2 系统迁移」第一反应就是找文件、复制、粘贴然后开机发现发行版没了、用户名变成 root 了、SSH 连不上了、Docker 也起不来了。我在第一次做这件事的时候就是这么把一整套训练环境搞废的——不是因为操作多复杂而是因为压根不知道自己在搬什么。WSL2 的本质是在 Windows 上跑的一个基于 Hyper-V 虚拟化能力构建的轻量级 Linux 虚拟机。你平时敲ls、装apt包操作的都是一个真实的 Linux 内核只不过它的文件系统不像传统虚拟机那样躺在一个.vmdk里而是躺在一个叫ext4.vhdx的动态虚拟磁盘文件里。这个文件默认藏在用户目录深处路径长得离谱通常是%LOCALAPPDATA%\Packages\发行版包名\LocalState\ext4.vhdx这种形状新版商店安装的 WSL 则会放在%LOCALAPPDATA%\wsl\{一串 GUID}\ext4.vhdx。理解这一点非常关键WSL2 迁移的核心就是把这个 vhdx 里的数据安全、完整地转移到新位置或新机器上并让 Windows 侧重新认得它。Windows 侧认得它的依据是什么是注册表里HKCU\Software\Microsoft\Windows\CurrentVersion\Lxss下面的那一堆键值记录了发行版名字、GUID、默认用户、启动方式等等。所以一次成功的迁移等于「数据搬家 注册信息重建」两件事同时做好少做一件都会出问题。那具体哪些场景会用到迁移我自己踩过的大致分三类。第一类是同机换盘原来用一块小容量固态装系统现在换成大容量固态或者把系统盘整个从 SATA 搬到 NVMe。第二类是换新电脑旧机器上的开发环境积累了两三年几百个包、几套 CUDA、一堆配置实在不想重头装一遍。第三类是单纯挪位置C 盘红了想把 WSL 从 C 盘搬到 D 盘本质上也是迁移。这三类的操作细节差别不小后面的章节我会分开讲。还有一类比较尴尬的情况是你只想迁移某一个发行版比如 Ubuntu 22.04 保留Ubuntu 20.04 和 kali 干脆重装。这时候就涉及导出单个发行版和批量处理的取舍我会在第 3 章给出具体做法。适合读这篇内容的人其实很广刚接触 WSL2 但马上要换机器的新手可以用它当操作手册已经用了一年半载、环境里有 CUDA、Docker、各类模型缓存的老用户可以重点看备份策略和迁移后收尾那几节至于已经在 WSL2 里跑 AI 训练、动辄几百 GB 缓存的同学我建议直接跳到第 4 章和第 5 章那里讲的是大体积数据的处理方式。2. 迁移方案怎么选三种主流做法逐一拆解选方案不能靠感觉得看你的数据量、环境复杂度和你能接受的停机时间。下面这张表是我这么多年总结出来的对比你可以先对号入座。方案原理优点缺点适用场景export / import把发行版打包成 tar再导入到新位置官方命令跨机器可靠可换名字和路径耗时随数据量线性增长大包容易几个 GB 起换新电脑、只迁移单个发行版直接搬 vhdx关掉 WSL 后复制 ext4.vhdx 文件速度快文件级复制省去打包解包需手动改注册表或重新挂载权限坑多同机换盘、只改路径文件级同步在 Linux 里用 rsync / tar 同步目录只搬需要的目录可控性最高环境配置、包管理状态容易漏只保留项目数据环境打算重建先说export和import这条路。它是微软官方提供的能力命令本身极简单wsl --export出一个 tar 包wsl --import把它解到指定目录。它最大的好处是跨机器、跨磁盘、跨版本都能用而且导出的是逻辑内容不是裸磁盘镜像所以不挑目标盘的文件系统格式。我一般推荐新手先用这套因为失败成本低tar 包还在重来一次不难。然后说直接搬 vhdx。这个做法最大的诱惑是快——假设你有一个 200 GB 的 vhdx复制一遍可能十几分钟而打包成 tar 再解开可能要一两个小时还额外占用双倍空间。但它的代价是你得自己处理注册表或者用wsl --mount --vhd手动挂载稍有不慎新系统里就会出现两个同名发行版或者挂不上。更坑的是权限问题下面细说。最后是文件级同步。这个方案听起来最「干净」但实际上最容易出问题。因为一个 Linux 开发环境的真正价值往往不在/home里那些源码而在/usr/local里你手动编译的东西、在/etc里你改过的配置、在包管理器数据库里记录的依赖关系。你只 rsync 一个 home 目录过去剩下的全靠重装那就不能叫迁移只能叫「部分备份」。所以我只推荐它在一种情况下使用你明确知道自己只要数据环境就是要重建。有一个决策点很多人会忽略就是要不要顺便升级发行版版本。比如你旧机器是 Ubuntu 20.04想借迁移的机会换成 22.04 或 24.04。我的建议是——分开做。先把 20.04 完整迁过去确认跑通再在目标机器上执行do-release-upgrade。两件事混在一起出问题时你根本分不清是迁移坏了还是升级坏了。这个顺序我吃亏过一次折腾了整整一个周末。另外还要提醒一句磁盘空间的问题。导出 tar 包通常和 vhdx 实际使用量接近导入时目标位置也要预留同样大小的空间。如果你的 vhdx 是 200 GB实际只用了 80 GB压缩后大概 6070 GB那么你至少要有 150 GB 的可用空间来做完整流程。空间不够的话先在 WSL 里清理缓存apt clean、docker system prune、清掉 pip 和 conda 的缓存再导出效果很明显。3. 实操从旧机器导出到新系统完整导入这一章是全文的骨架我会按真实操作顺序一步步写包含每一步的目的、命令、参数含义和我踩过的坑。整套流程大约需要 30 分钟到 2 小时取决于你的数据量。3.1 迁移前的环境盘点与信息留档动手之前一定要先留档。很多迁移失败后的痛苦都来自「忘了原来是怎么配的」。先在 Windows 侧打开 PowerShell跑wsl --list --verbose输出会列出所有发行版、状态和 WSL 版本。重点看版本那一列是不是 2如果有 1 的迁移前建议先转换wsl --set-version Ubuntu-22.04 2同时记下内核版本wsl --status wsl --version进到 Linux 里再采几项关键信息uname -a cat /etc/os-release id echo $SHELL cat /etc/wsl.confid这条尤其重要它会告诉你用户名和 uid/gid。Unix 系统里文件归属是靠数字 uid 认的不是靠用户名所以换机器后如果原来 uid 是 1000、新机器上默认用户变成了 1000 以外的号码你的 home 目录就会出现「文件存在但没权限改」的诡异状态。把 uid 记下来后面收尾时用得上。还有一个容易被忽略的点是发行版列表和各自用途。如果你有 docker-desktop、docker-desktop-data 这类由 Docker Desktop 自动创建的发行版它们不建议手动迁移正确的做法是新机器上重装 Docker Desktop然后重新指向数据目录。把这一点记下来能省掉后面一堆麻烦。提示整个盘点过程建议截图或者写到笔记里包括发行版名称、默认用户名、uid、发行版版本、内核版本、常用端口。迁移后对照检查比凭记忆靠谱得多。3.2 导出命令很短细节很多第一步是彻底停掉 WSL这一步不能省wsl --shutdown确认所有发行版都处于 Stopped 状态再跑一次wsl --list --verbose看。为什么要这么严格因为 vhdx 是动态磁盘运行中有缓存未落盘直接导出可能得到一个状态不一致的包。我有一次偷懒没关干净导出来的包里/var/lib/dpkg锁文件还在导入后 apt 直接罢工。然后执行导出wsl --export Ubuntu-22.04 D:\backup\ubuntu2204_20250101.tar参数含义很直白--export后面先跟发行版名再跟目标文件路径。这里有几个实操细节值得说。一是目标路径不要放在 C 盘因为导出文件体积可能很大容易把系统盘撑爆。放到另一块盘或者移动硬盘上更稳妥。二是文件命名带上日期你会感谢未来的自己——尤其是当你做了两三次迁移、手边有三四个 tar 包的时候。三是tar 包本质是个归档文件理论上可以用tar -tf在 Linux 里查看内容出问题的时候可以用这个做初步检查。如果你要迁移多个发行版就重复执行每个发行版一个包。这一步的耗时和你的数据量成正比我在一台有 120 GB 环境的机器上导出花了大约 25 分钟。导出完成后强烈建议做一次校验把包复制到另一块物理磁盘或者算个哈希存下来。Get-FileHash D:\backup\ubuntu2204_20250101.tar -Algorithm SHA256记录下这个哈希导入前再算一遍如果不一致说明复制过程中出错了。这一步听起来多余但我在用移动硬盘搬运一个大包的时候真的遇到过一次文件损坏早发现省了两小时。注意导出过程不要中断尤其是在使用笔记本的时候记得插上电源。PowerShell 窗口关闭会让导出直接失败得到一个不完整的包。3.3 新系统上把 WSL2 环境先搭好到了新机器别急着导入先把 WSL2 底座装正确。顺序错了会出现「导入成功但启动不了」的情况。首先确认 Windows 的虚拟化功能是开的在 PowerShell 里执行Get-ComputerInfo -Property HyperV*或者直接看systeminfo | Select-String Hyper-V如果虚拟化没启用需要到 BIOS/UEFI 里打开虚拟化相关选项不同主板叫法不同常见的是 Intel VT-x 或 AMD-V。这一步必须在固件层做Windows 里改不了。开启之后再执行系统功能启用dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart两条命令执行完重启一次。重启后安装 WSL 主体并更新内核wsl --install --no-distribution wsl --update--no-distribution的意思是只装 WSL 本体不自动装 Ubuntu因为我们后面要自己导入。wsl --update会拉取最新的 WSL 内核这一步很关键——新内核对新硬件的支持更好也修复了不少老版本的挂载问题。装完之后用wsl --version确认输出里有版本号看到版本信息说明底座正常。如果这一步报错多半是系统功能没启用或者版本太老先把 Windows 更新到较新的版本再重试。还有一种常见情况是公司电脑、权限受限跑不了 dism。这时候可以让管理员帮忙启用功能或者联系 IT 处理。自己硬闯权限限制通常没有好结果反而会把系统搞乱。3.4 导入到指定目录并处理默认用户问题底座好了开始导入wsl --import Ubuntu-22.04 D:\wsl\ubuntu2204 D:\backup\ubuntu2204_20250101.tar --version 2三个位置参数依次是发行版名称可以自定义不必和原来一样、安装目录、tar 包路径。--version 2明确指定用 WSL2不加的话某些老版本会默认成 1。导入完成后你敲wsl -d Ubuntu-22.04进去会发现问题当前用户是 root。这是 import 的固有行为它不会记住你原来的默认用户因为注册表里那条记录是新建的。解决办法有两种第一种是改/etc/wsl.confsudo tee /etc/wsl.conf /dev/null EOF [user] defaultyourname [boot] systemdtrue EOF然后在 Windows 侧wsl --shutdown重新进入生效。这里顺手把 systemd 打开是有必要的现在很多服务Docker、部分数据库、桌面环境相关组件都依赖 systemd不开的话你会遇到一堆「服务起不来」的问题。第二种是在 Windows 侧用发行版自带的配置程序比如 Ubuntu 的ubuntu2204.exe config --default-user yourname这个可执行文件的名字取决于你安装的发行版包可以在开始菜单里找或者在%LOCALAPPDATA%\Microsoft\WindowsApps目录下查看。两种方式效果一样我一般用第一种因为它顺带把 systemd 配好了。导入完成后的目录结构值得看一眼D:\wsl\ubuntu2204下面会出现一个ext4.vhdx这就是你的新虚拟磁盘。整个目录可以整体复制到别处只要注册表路径对得上或者重新 import 一次就能继续用。3.5 迁移后的收尾清单一条都别漏导入成功不等于迁移完成下面这些收尾动作我基本每次都要过一遍漏掉哪条都会在某天以奇怪的方式报复你。第一项检查 uid/gid 是否和原来一致。进去跑id如果 uid 变了而你的 home 目录文件归属还是旧 uid就会看到一堆文件属于一个数字用户。修复方式是改 uidsudo usermod -u 1000 yourname sudo groupmod -g 1000 yourname sudo find / -user olduid -exec chown -h yourname {} \;用之前记下的 uid 对照着改别凭感觉。第二项SSH 密钥权限。你~/.ssh里的私钥权限必须是 600目录是 700。如果迁移过程中经过了 Windows 文件系统比如曾经放在/mnt/d下面权限会被压成 777SSH 会直接拒绝使用chmod 700 ~/.ssh chmod 600 ~/.ssh/id_rsa chmod 644 ~/.ssh/id_rsa.pub ~/.ssh/known_hosts第三项DNS 和网络。新机器上如果发现域名解析慢或者某些域名解析不了检查/etc/resolv.conf必要时在/etc/wsl.conf里加上[network] generateResolvConf true同时如果你的 apt 或者 pip 下载速度慢换成就近的公共镜像站能明显改善这个属于常规优化跟迁移本身无关但顺手做了体验会好很多。第四项时间同步。WSL2 的时间偶尔会漂移尤其是机器休眠唤醒之后。一条命令搞定sudo hwclock -s第五项Docker 相关。如果你原来用 Docker Desktop 的 WSL2 后端新机器上重装 Docker Desktop它会自己创建 docker-desktop 发行版。你的镜像和容器数据如果原来导不出来就老老实实重新拉。如果你是直接在 WSL 里装的 Docker Engine那要把docker用户组重新加一遍并确认 systemd 起来了。第六项检查环境变量和 shell 配置。~/.bashrc、~/.zshrc、/etc/profile.d里如果写死了旧机器的路径比如某个盘符或者用户名要改掉。我见过有人.bashrc里写死了/mnt/e/xxx换机器后每次开终端都报一行错虽然不致命但看着难受。4. 直接搬 vhdx 的做法与它的代价如果你只是想把 WSL 从 C 盘挪到 D 盘或者同机换盘其实有比 export/import 更快的方法。我在这里单独开一章是因为这条路省时间但埋雷必须先说清楚。最省事的版本是用 WSL 自带的管理命令需要较新的 WSL 版本wsl --shutdown wsl --manage Ubuntu-22.04 --move D:\wsl\ubuntu2204这条命令会把 vhdx 挪到新位置并自动更新注册表用户配置基本原样保留。整个过程的耗时接近文件复制比打包解包快不少。用完之后建议顺便把它设置成稀疏文件可以省下不少空间wsl --manage Ubuntu-22.04 --set-sparse true如果你的 WSL 版本比较老没有--manage那就得手动搬。步骤是wsl --shutdown把整个发行版目录包含 ext4.vhdx复制到新位置然后在 PowerShell 里查注册表项Get-ChildItem HKCU:\Software\Microsoft\Windows\CurrentVersion\Lxss | ForEach-Object { Get-ItemProperty $_.PSPath | Select-Object DistributionName, BasePath }找到对应发行版把BasePath改成新目录注意结尾要带反斜杠。改注册表有一定风险改之前先导出备份reg export HKCU\Software\Microsoft\Windows\CurrentVersion\Lxss D:\lxss_backup.reg这里特别说一下「直接复制 vhdx」为什么容易出权限问题。核心原因在于Windows 文件系统对 Linux 权限位的处理是模拟的。当你把 vhdx 放到一个 Windows 认为「网络位置」或者「可移动设备」的路径上WSL 挂载时可能会给整个文件系统套上一层默认权限导致里面的所有文件都变成 777包括本该是 600 的私钥、本该是 644 的配置文件。表现出来就是 SSH 不工作、sudo提示权限不安全。所以有个原则vhdx 一定要放在本地 NTFS 磁盘上不要放在 exFAT、FAT32 的移动硬盘或者网络位置上长期运行。临时搬运可以但迁移完成后必须落到本地盘。另一个坑是 vhdx 的膨胀。动态磁盘只增不减你在 WSL 里删了 50 GB 文件vhdx 体积一点都不会变小。迁移完想顺手瘦身的话可以手动压缩wsl --shutdown diskpart进入 diskpart 交互界面后依次执行select vdisk fileD:\wsl\ubuntu2204\ext4.vhdx attach vdisk readonly compact vdisk detach vdisk exit或者在较新版本里直接用--set-sparse true更省事。压缩前务必先关掉 WSL否则会失败或者损坏磁盘。注意压缩 vhdx 属于有风险操作动手前一定把 vhdx 复制一份到别的盘做备份。几百 GB 的环境压缩失败又没备份那种心情我不想让你体验。5. 换了系统盘怎么办整体迁移的先后顺序现在回到很多人真实面对的处境本地电脑原来用一块小容量 SSD 装系统现在买了一块更大的 SSD想把整套环境搬过去。这个问题比单纯迁移 WSL 复杂因为涉及「系统盘迁移」和「WSL 迁移」两件事的排序。我的建议顺序很明确先把 Windows 系统整体迁到新盘再迁 WSL2 环境。理由很直接——WSL 的注册表信息、路径依赖都绑在 Windows 用户账户上如果 Windows 系统本身还在做迁移WSL 的引用关系随时可能失效。先让 Windows 在新盘上稳定跑起来再动 WSL问题排查会简单得多。系统盘迁移这块市面上的分区管理和备份类工具都能做本质是把旧盘上的分区按结构克隆到新盘再调整引导。操作时的注意点有这么几个。第一迁移前把 Windows 里的快速启动和休眠关掉否则分区可能处于非正常状态克隆出来的系统有概率启动异常。可以在管理员 PowerShell 里执行powercfg /h off第二迁移完成后先不要格式化旧盘。至少保留一两个星期确认新系统、WSL、所有开发工具都正常再考虑清理。我见过有人迁移完当天就把旧盘格了第二天发现某个环境的授权绑在旧盘序列号上哭都没地方哭。第三新盘容量要留足余量。现在 WSL 环境动辄上百 GB加上 Windows 本身、各种缓存如果新盘只比旧盘大一点点你很快又会遇到空间紧张。我个人建议至少留 30% 的空闲空间SSD 的性能和寿命都受益于这个余量。第四分区对齐。这个基本不用你操心现代工具都会自动处理好但如果你手动分区注意 4K 对齐否则 SSD 读写性能会掉得厉害。判断方法是用工具查看分区的起始扇区是否能被 8 整除4K 8 个 512B 扇区。WSL 迁移放在系统迁移之后操作就是第 3 章那套流程。有一个小优化既然都要搬了顺便把 WSL 数据目录直接指定到大容量盘上以后就不用再折腾。导出导入时把安装目录选成D:\wsl\发行版名这类位置一步到位。还有一点值得提如果你在 WSL 里跑 AI 训练或者大型数据处理IO 性能是瓶颈。把 vhdx 放在 NVMe 上和放在机械硬盘上训练时的数据读取速度差距可能有好几倍。既然换了新盘顺手确认一下 WSL 目录是不是在新盘上这个收益比什么都实在。6. 常见问题速查与排查技巧迁移过程里会遇到的问题其实高度集中在几个点上我整理成一张表方便你对照排查。现象可能原因排查与解决启动报错提示虚拟化未启用BIOS/UEFI 里虚拟化功能关闭进固件设置开启 Intel VT-x / AMD-V保存重启导入成功但进不去报 0x80370102系统功能未启用或内核过旧重新执行 dism 启用两项功能并wsl --update进去之后是 root 用户import 不保留默认用户修改/etc/wsl.conf的[user]段或运行发行版配置程序文件全部没有写权限uid 变化或 vhdx 放在了非本地 NTFS 上核对 uid 并 chown把 vhdx 挪回本地盘SSH 报私钥权限不安全文件权限是 777chmod 600 ~/.ssh/id_rsa域名解析慢或失败resolv.conf 配置问题检查/etc/wsl.conf的 generateResolvConf 设置磁盘越用越大但不释放vhdx 动态磁盘只增不减先备份再用 diskpart compact 或设 sparse某些工具检测不到 WSL2 环境版本识别异常或内核信息不匹配用uname -r确认内核带 Microsoft 标识必要时更新 WSLDocker 起不来systemd 未启用或用户组未加开启 systemd重新把用户加入 docker 组中文显示成方块或乱码locale 未配置安装语言包并设置 locale除了表里这些还有几个排查思路值得单独说。怎么看当前到底是 WSL1 还是 WSL2用wsl --list --verbose看 VERSION 列最直接。另一个办法是在 Linux 里跑uname -r输出里带microsoft-standard-WSL2字样的是 WSL2WSL1 的内核版本号形态完全不同。WSL2 老断网怎么办这个问题的成因比较多常见的有 Windows 侧的节能策略、网卡驱动、以及 WSL 网络模式的配置。可以先从简单的入手更新网卡驱动关掉网卡的节能选项然后在.wslconfig里调整内存和处理器分配。如果还是不稳定检查一下是不是同时开着其他虚拟化软件资源竞争也会导致网络异常。wsl --update特别慢或者卡住怎么办这通常和网络环境有关可以试着错开高峰期或者检查 Windows 更新服务是否正常。如果实在更新不动也可以找离线的 WSL 更新包手动安装但要确认版本和系统架构匹配别装错。导入之后 hostname 变了有影响吗一般不影响使用但如果你有脚本或者服务依赖原来的主机名需要手动改。改法是编辑/etc/hostname和/etc/hosts然后重启 WSL。迁移后 pip 或者 conda 的虚拟环境报错大概率是路径写死了。conda 环境的路径记录在envs目录下的配置里如果旧路径和新路径不一致需要重建环境或者手动改配置。这也是我建议大环境用 Docker 而不是裸装 conda 的原因之一迁移时一个镜像包解决。怎么确认迁移后的数据和原来一致最靠谱的办法是迁移前记录几个关键指标du -sh各个大目录的体积、dpkg -l | wc -l的包数量、pip list | wc -l的数量、几个重要项目的 git 状态。迁移后逐项对比数量对得上基本就没问题。还有一个经验值得单独强调迁移过程中保留旧环境直到新环境完全跑通。这一步很多人会跳过觉得「导出成功了就删掉旧的」结果新环境某个东西没配好回头已经没得查了。我的做法是旧机器上的 WSL 至少保留两周或者旧 vhdx 复制一份到移动硬盘放着确认一切正常再清理。7. 我在实际操作中攒下的几条体会聊了这么多流程最后说点不那么「标准」但很有用的经验。第一条是关于数据量的预判。很多人根本不知道自己 WSL 里占了多少空间直到导出的时候才发现要搬 200 GB。我现在的习惯是每月看一次占用du -h --max-depth1 / 2/dev/null | sort -hr | head -20看完心里有数也顺便能发现某些缓存目录失控增长。Docker 的/var/lib/docker、pip 缓存、conda 的 pkgs 目录这三个是空间杀手迁移前清理一遍能省下大量时间。第二条是关于不要迷信一次性迁移。环境越复杂一次成功的概率越低。我的做法是分批搬先搬一个小的发行版练手跑通整套流程确认新机器的 WSL2 底座、systemd、网络、用户权限都没问题再去搬那个几百 GB 的主力环境。这样即使主力环境出问题你也已经知道自己错在哪一步了。第三条是给迁移后的环境留一个记录文件。我现在会在每个 WSL 发行版里放一个~/MIGRATION_NOTES.md记录这个发行版的用途、装的版本、关键配置文件的位置、以及每次迁移的日期和操作。听起来很土但换机器的时候打开一看比任何记忆都可靠。第四条是关于 systemd 的。现在 WSL2 默认可以开 systemd 了但它在某些场景下会影响启动速度。如果你的发行版只是用来跑命令行工具不需要后台服务可以不开如果要用 Docker、数据库、后台任务那就必须开。这个取舍按需选择别盲目跟风。第五条也是我觉得最重要的一条迁移前先在纸上把步骤写一遍。包括哪台机器做什么、命令是什么、备份放在哪、失败了怎么回退。我现在的清单大概有二十来项看起来很啰嗦但每次都能省下至少一个小时的debug时间。迁移这种低频高危操作值得花二十分钟把事情想清楚。如果你后续还想扩展这套流程有几个方向可以试试。一是把它脚本化用 PowerShell 和 Bash 各写一份参数化发行版名和路径以后一条命令搞定。二是搭一个有版本记录的备份机制比如每周自动导出一次 tar 包并保留最近三份。三是如果你有多台机器可以考虑用统一的配置文件管理 shell 环境迁移时只要同步这一个仓库就行。这些就不展开了做到哪一步取决于你的环境复杂度。