
1. 装 WSL 之前先弄清它和虚拟机的本质差别第一次在 Windows 上装 Linux 子系统的人十个里有七个会在同一个地方翻车把 WSL 当成轻量版虚拟机来理解然后按虚拟机的思路去配内存、配网络、配磁盘最后发现行为完全对不上。我最早做跨平台开发的时候也是先在 VMware 里跑 Ubuntu每次改一行代码要等编译、要开共享文件夹、要配 NAT后来换成 WSL 之后工作流整个变了。所以这篇文章不急着贴命令先把它是什么、为什么这么快、什么时候不该用它讲透后面所有操作你才做得明白。1.1 它不是虚拟机是翻译层加上一个真内核虚拟机和 WSL 的区别用一个类比就能说清。虚拟机是在你家里隔出一个独立的房间装空调、装水管、拉电线里面自成一套WSL2 则是把 Linux 内核塞进一个极轻的虚拟机里但这个虚拟机只跑内核其他所有用户态的东西都直接和 Windows 打通文件、进程、网络、剪贴板都能互相看见。WSL1 更极端它压根没有 Linux 内核是把 Linux 系统调用实时翻译成 Windows 系统调用。这个区别直接决定了三件事。第一WSL 启动只需要一两秒内存占用通常只有几百 MB而完整虚拟机起步就是 2GB 内存和几十秒开机时间。第二WSL 里可以直接执行.exe文件你在 Ubuntu 里敲notepad.exe test.txt是真的会弹出记事本的这个能力在虚拟机里想都别想。第三也是最重要的一点WSL 的文件系统和 Windows 文件系统是两套东西跨边界访问会非常慢这一点后面会专门用一个章节讲因为九成的WSL 好卡问题都出在这里。WSL 的定位非常明确给开发者提供一个能跑 Linux 工具链、能跑服务端程序、能和 Windows 侧的编辑器无缝配合的环境。它不是给你练运维、练内核、练系统管理的也不是给你跑桌面程序的。想学 Linux 服务器管理、想跑多台机器组网实验的时候老老实实开虚拟机反而更省事。1.2 WSL1 和 WSL2 的分水岭别选错现在默认装出来的是 WSL2但很多人机器上还留着老的 WSL1 发行版问题就来了。两者的差异不是新版旧版这么简单而是架构上的根本不同。我整理了一张对照表你在决定用哪个之前先扫一眼。对比维度WSL1WSL2内核无系统调用翻译真实 Linux 内核启动速度极快亚秒级快1-2 秒跨系统文件访问较快慢尤其大量小文件Linux 原生兼容性部分系统调用缺失完整Docker 支持基本不可用原生支持内存占用极低几百 MB 起随负载增长网络与主机共享独立虚拟网卡有 NAT选型的判断标准其实很简单要跑 Docker、要跑需要内核特性的服务比如某些数据库、eBPF 工具、Kubernetes 本地集群必须 WSL2只是想在 Windows 上敲几条 Linux 命令、跑个 Python 脚本、用 grep 和 sed 处理文本WSL1 够用而且更轻。不过实践中我建议直接上 WSL2因为生态已经完全转向它很多新工具链默认只测 WSL2用 WSL1 会遇到各种莫名其妙的兼容问题。还有一点容易忽略WSL2 的内存是动态分配的它不会一开机就吃掉你一半内存但会在你跑编译、跑容器的时候快速膨胀而且默认情况下不会主动归还。这是后面要单独调的参数先记住这个现象。1.3 装机前必须确认的三项前提在动手之前先花三分钟确认三件事能省掉后面一小时的排查。第一是系统版本。wsl --install这条一体化命令需要 Windows 10 版本 2004内部版本 19041及以上或者 Windows 11。低于这个版本你只能走手动分步安装的老路。用winver命令可以查看当前版本跑一下心里有数。第二是虚拟化支持。WSL2 依赖 Hyper-V 的轻量虚拟化能力所以必须在 BIOS 里打开 CPU 虚拟化。任务管理器 → 性能 → CPU右下角看虚拟化这一项是不是已启用。如果是已禁用需要重启进 BIOS 找 Intel VT-x 或 AMD-V 打开。很多人装到一半报 0x80370102 这个错误码根源就是这里。注意WSL2 不需要你在 Windows 功能里安装完整的 Hyper-V只要虚拟机平台这个组件就够了这个区别后面会讲。第三是磁盘空间和位置。默认情况下 Ubuntu 发行版会装在C:\Users\用户名\AppData\Local\Packages\下面用一个叫ext4.vhdx的虚拟磁盘文件承载。这个文件是会持续增长的跑一段时间之后轻松几十 GB。如果你 C 盘本来就紧张最好在安装前就规划好装完再迁移会多一道手续。我自己的习惯是直接留出 50GB 空间或者装完立刻迁到 D 盘。提示不要在安装过程中切换网络或者挂载新的磁盘WSL 的首次安装对网络稳定性比较敏感中途断网容易出现发行版注册不完整的情况。2. 一条命令之外的完整安装链路wsl --install是官方主推的一体化入口但它只是一个封装底层做的事情比你想象的多。搞清楚它内部干了什么出问题的时候你才知道从哪一步开始手动接管。2.1 wsl --install 到底做了什么这条命令实际执行了四件事启用适用于 Linux 的 Windows 子系统可选组件、启用虚拟机平台可选组件、下载并安装 WSL2 的 Linux 内核更新包、把默认发行版现在是 Ubuntu拉下来并注册。整个过程需要重启一次重启后会自动弹出终端让你设置用户名密码。执行之前确保你的终端是以管理员身份运行的 PowerShell 或 Windows Terminal。普通权限跑这条命令会在启用可选组件那一步失败。# 以管理员身份打开 PowerShell wsl --install如果你已经装了 WSL 但想换一个发行版或者想指定版本可以用参数控制# 查看所有可在线安装的发行版 wsl --list --online # 安装指定发行版 wsl --install -d Ubuntu-22.04 # 安装完设置默认发行版 wsl --set-default Ubuntu-22.04这里有个细节wsl --install装完之后默认版本不一定是你想要的。用下面的命令确认wsl --status wsl --list --verbosewsl --status会告诉你默认版本是 1 还是 2--verbose会列出每个发行版跑在哪个版本上。如果是 1用wsl --set-default-version 2改默认值再用wsl --set-version Ubuntu-22.04 2把已有的发行版转过去。注意转换过程会把整个发行版重新打包一遍数据多的话要等几分钟中途不要关窗口。2.2 一条命令失败时的分步手动安装wsl --install卡住的原因通常有两类Windows 版本太低或者可选组件被组策略、安全软件限制了。这种情况下走手动分步更靠谱每一步都能看到结果。第一步用命令行启用两个组件。图形界面的启用或关闭 Windows 功能勾选法容易漏东西命令行更干脆dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart两条命令都执行完之后必须重启没有重启就装内核包会把系统搞成半吊子状态。第二步安装 WSL2 内核更新包。这个包是一个独立的 msi 文件官方名称是wsl_update_x64.msi。如果你系统里之前装过老版本 WSL这一步尤其不能跳过因为老内核和新版发行版之间的兼容性很差会出现WSL 版本过旧请运行更新命令这类提示。内核包安装完之后再跑一次wsl --set-default-version 2。第三步安装发行版。除了用wsl --install -d还有一种完全离线的方式适合网络环境不稳定的时候把发行版的 appx 安装包下到本地用 PowerShell 直接装。# 在存放 appx 包的目录下执行 Add-AppxPackage .\Ubuntu_2204.1.7.0_x64.appx这种方式的好处是安装包里已经带了完整的 rootfs不需要在线拉取装上之后首次启动直接进入用户创建流程。第四步验证。三个命令一次性确认状态wsl --list --verbose # 看发行版列表和版本号 wsl --status # 看默认版本和内核版本 wsl --version # 较新版本才有输出组件详细版本如果wsl --list --verbose里 STATE 显示 Running 但版本号那一列还是 1说明转换没成功重新执行wsl --set-version 发行版名 2。2.3 首次启动后的用户名与密码设置发行版第一次启动会进一个初始化界面让你输入 UNIX 用户名和密码。这一步有三个坑我挨个说。第一个坑用户名不要用大写字母也不要用中文。Linux 里用户名带大写虽然技术上允许但很多工具链会在生成路径时出问题比如 Docker 的挂载、某些编译脚本的临时目录。全小写加数字最稳。第二个坑密码输入的时候屏幕没有任何回显不显示星号也不显示圆点。很多人以为键盘没反应反复敲其实是正常现象输完直接回车就行。这个密码是 sudo 密码忘了要重置比较麻烦先想好。第三个坑初始化完成后你会在/etc/passwd里看到自己的用户但默认的 shell 环境变量是继承 Windows 的。检查一下echo $PATH如果里面混着一大堆/mnt/c/...的路径说明 Windows PATH 被追加进来了。这个设计在调用 Windows 程序时很方便但在执行同名命令时会出岔子比如系统里同时存在 Windows 的 python 和 Linux 的 python3。解决办法是在/etc/wsl.conf里关掉[interop] appendWindowsPath false改完执行wsl --shutdown重启发行版生效。关掉之后如果你想调用 Windows 程序得用完整路径或者自己加个别名。3. 卡住、报错、下载龟速把问题拆成三类去查WSL 的安装问题看着五花八门其实归类之后就三类网络通道慢、版本不匹配、虚拟化没就位。按这个顺序排查基本不会绕远路。3.1 下载中途卡住先分清是慢还是断很多人反馈wsl --install停在某个百分比不动第一反应是网速差。实际上 WSL 的发行版下载走的是应用商店的分发通道和普通下载的链路不一样卡住往往是连接被重置而不是带宽不足。区分方法很简单看进度条是否在缓慢前进。如果数字在涨只是慢等着就行一个 Ubuntu 镜像大概几百 MB慢一点十几分钟也下来了。如果数字完全不动超过五分钟那就是连接断了CtrlC 中断之后重来。真正高效的应对方式是换一条路不要在线拉改用离线包安装。前面 2.2 节讲的Add-AppxPackage方式就是把整个 rootfs 提前拿到本地再装完全绕开在线通道。离线包可以从官方文档页面找到对应的直链下载下来之后本地安装速度取决于你自己的网络稳定得多。还有一个小技巧如果你只想要一个干净的、不带图形组件的最小发行版可以选 Ubuntu 而不是 Ubuntu-22.04 这类带版本后缀的包前者体积更小装完再自己升级版本就行sudo apt update sudo apt full-upgrade -y sudo do-release-upgrade3.2 版本过旧相关的报错本质是内核包没更新your version of windows subsystem for linux is too old 这个提示我在不同机器上见过好几次共同点是系统里装过旧版 WSL后来又升级了 Windows内核包没跟着更新。处理步骤固定先去官方渠道拿最新的wsl_update_x64.msi装上然后执行wsl --update wsl --shutdownwsl --update会去检查并拉取最新版本的 WSL 组件新版本已经改成独立的 MSIX 包不再依赖系统组件跑完之后再wsl --version看看版本号有没有变。如果wsl --update本身也失败那就只能手动下载 MSIX 包双击安装或者用Add-AppxPackage装。注意不要在网上随便找所谓的离线包安装来源不明的二进制包风险很高。优先从官方文档给出的地址获取。3.3 虚拟化与内存相关错误码的处理这类报错的典型代表是0x80370102含义是无法启动虚拟机因为所需的虚拟机监控程序未运行。排查链路我按实际发生频率排序错误现象最可能原因处理方式0x80370102BIOS 虚拟化未开启重启进 BIOS 打开 VT-x / AMD-V0x80370102虚拟机平台组件未启用用 dism 命令启用后重启0x80370102第三方虚拟化软件冲突关闭冲突软件后重启启动后立即退出内核包版本不匹配更新 WSL 内核包WSL2 频繁重启内存被挤爆用 .wslconfig 限制内存补充说明一下虚拟化软件冲突这一项。如果你机器上装了其他依赖虚拟化的软件它们可能抢占了虚拟化层。这种情况下先全部退出再启动 WSL 验证。验证通过之后再逐个恢复能定位到具体是哪个在冲突。另外还有一个常被忽视的场景在 Windows 的内核隔离或者内存完整性功能开启的情况下某些机器的虚拟化层会被影响。如果你排除了前面所有原因还是报错可以去 Windows 安全中心 → 设备安全性 → 内核隔离临时关掉内存完整性再试一次。测试完记得根据实际需要决定是否恢复。4. 环境落地的头一天把工具链一次配到位装完只是开始真正决定体验的是接下来一两个小时的配置。这一步做扎实后面半年都不用折腾做马虎以后每次用都想骂人。4.1 换源、装基础工具与终端体验第一步永远是换软件源。默认的源在国外apt update慢得让人怀疑人生。换源的方式因发行版而异Ubuntu 的源配置文件在/etc/apt/sources.list改之前先备份sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak sudo sed -i s|http://archive.ubuntu.com|https://mirrors.aliyun.com|g /etc/apt/sources.list sudo apt update换成国内镜像之后apt install的体验会有质的提升。接下来装一批基础工具我列一个自己每台机器都会装的清单sudo apt install -y build-essential git curl wget unzip zip \ p7zip-full vim htop tree net-tools dnsutils \ python3-pip python3-venv dos2unix这里每一项都有理由。build-essential提供 gcc 和 make很多 Python 包和 Node 原生模块编译时都要用p7zip-full是为了处理中文名压缩包后面细讲dos2unix处理 Windows 和 Linux 换行符差异tree和htop是日常查看目录和进程的刚需。Git 装完之后立刻配一下git config --global user.name 你的名字 git config --global user.email 你的邮箱 git config --global core.autocrlf input git config --global credential.helper storecore.autocrlf input这一条很关键。Windows 和 Linux 的换行符不一样不加这个配置从 Windows 侧签出的文件在 Linux 里会多出一堆\r脚本执行时报bad interpreter就是这个原因。4.2 Windows 和 Linux 两边文件互访的正确姿势这是 WSL 使用中最大的性能陷阱也是我最想强调的一点。WSL2 的文件系统有两侧Linux 侧/home/你的用户名/存放在ext4.vhdx里是真正的 ext4 文件系统Windows 侧/mnt/c/、/mnt/d/是通过 9P 协议挂载过来的属于跨系统访问结论很简单项目代码放在 Linux 侧不要在/mnt/c下跑编译和 git 操作。原因是/mnt/c的每一次文件读写都要经过协议转换小文件多的场景下性能差距能到十倍以上。我实测过一个前端项目npm install放在/mnt/c下要跑七八分钟挪到 Linux 侧只要一分钟出头。那如果代码已经在 Windows 上了怎么办有两种做法。一是直接把项目克隆到 Linux 侧用 VS Code 的远程功能打开下一节讲。二是如果必须在 Windows 侧保留一份用rsync做同步而不是直接在/mnt/c下操作。从 Windows 访问 Linux 文件最方便的是在资源管理器地址栏输入\\wsl$\Ubuntu-22.04\home\你的用户名这个路径会直接映射到 Linux 侧的家目录而且读写速度是原生的因为走的是 WSL 的虚拟网络文件共享。你在 VS Code 里用普通方式打开这个路径编辑体验和本地文件几乎没差别。注意别把它当成/mnt/c那套逻辑来理解两者方向相反性能特征也完全相反从 Windows 访问\\wsl$快从 Linux 访问/mnt/c慢。4.3 VS Code 接进 WSL 的正确配置在 WSL 里写代码最舒服的组合是 Windows 侧装 VS Code通过 Remote - WSL 扩展连进来。装扩展的步骤不复杂在 VS Code 里搜 WSL安装官方那个叫 WSL 的扩展Remote Development 扩展包的一部分然后按 F1 输入WSL: Connect to WSL或者干脆在 WSL 终端里 cd 到项目目录执行code .。连上之后有几个配置项值得调。第一个是默认 shellCtrlShiftP搜 Terminal: Select Default Profile选 Ubuntu 的那个这样集成终端直接开在 WSL 里。第二个是文件监听性能在设置里加上{ files.watcherExclude: { **/node_modules/**: true, **/.git/objects/**: true, **/target/**: true }, files.useExperimentalFileWatcher: true }大型项目里不排除node_modules文件监听会吃掉大量 CPU风扇转得飞快。第三个是终端字体。想在 WSL 里获得接近 macOS 那种细腻的代码观感字体选择占七成渲染设置占三成。我在几台机器上试下来的组合是JetBrains Mono等宽比例舒服字符辨识度高连字设计克制编程场景首选Maple Mono国内开发者做的开源等宽字体中文标点对齐处理得很好配中文注释很整齐Sarasa Term SC更纱黑体终端版中文覆盖完整适合注释里大量写中文的场景Cascadia CodeWindows 自带配合 Windows Terminal 的渲染效果不错零成本Windows Terminal 里对应的设置项字号 12 到 13 之间行高 1.2开启连字ligatures字体粗细选 Regular 或者 Retina 风格的 Light。如果觉得字有点糊检查一下有没有开 ClearType以及是否把终端设成了使用亚像素抗锯齿。这几项调完观感提升非常明显。5. 长期使用中真正会咬人的几个坑前面都是能一次性解决的配置问题这一节讲的是用了几个月之后才会暴露出来的坑也是我踩得最惨的几处。5.1 中文乱码与解压乱码Windows 打出来的 zip 包在 Linux 里解压出来文件名全是乱码这是最经典的编码问题。原因是压缩时用的是 GBK 编码存文件名解压工具默认按 UTF-8 读一对不上就乱。三种解法按推荐程度排序。第一种用7z代替unzip它会自动探测编码7z x 压缩包.zip第二种明确告诉unzip用 GBKunzip -O CP936 压缩包.zip注意不是所有发行版的unzip都编译了-O参数跑失败的话就换第一种。第三种已经解压出来的乱码文件用convmv批量改名sudo apt install convmv convmv -f gbk -t utf-8 -r --notest ./--notest是真正执行改名不加的话只预览不改建议先不加跑一遍确认结果再执行。另外还有一类乱码是终端本身的问题。检查localelocale如果LANG显示的是C或者POSIX中文会显示成问号。生成并设置中文 localesudo apt install locales sudo locale-gen zh_CN.UTF-8 sudo update-locale LANGzh_CN.UTF-8update-locale是写进/etc/default/locale的重启 WSL 后生效。不过说实话我自己习惯把 LANG 保持成en_US.UTF-8只在需要的时候临时切。因为英文 locale 下命令报错信息更好搜中文 locale 有时候会把错误信息翻译得不知所云。5.2 权限与文件属主那些事/mnt/c下的文件在 WSL 里看永远是777所有文件都是可执行chmod改了也没用重启就恢复。原因是 9P 挂载默认不带元数据支持。如果你确实需要在/mnt下维护权限得在/etc/wsl.conf里打开 metadata[automount] enabled true root /mnt/ options metadata,umask22,fmask11改完wsl --shutdown重启。加上metadata之后WSL 会在 NTFS 的扩展属性里存 Linux 权限位chmod就能生效了。还有一个更隐蔽的坑在/mnt/c下执行 git 操作可能会把整个仓库的权限位改掉。因为 Windows 侧不记录执行位每次检出都当成 644而 git 记录的可能是 755来回切换就产生大量权限变化的 diff看着很烦。避免方式还是那一句git 仓库放 Linux 侧。关于 sudo有一个小技巧值得说。默认 sudo 密码每次都要输如果只是自己本机开发环境可以配置免密sudo visudo在文件末尾加一行把 username 换成你自己的username ALL(ALL) NOPASSWD: ALL注意这只适合纯个人开发机。任何多人使用或者有对外服务的机器都不要开免密 sudo。5.3 Docker 与 WSL 的集成边界在 WSL 里用 Docker 有两条路差别很大。一条是装 Docker Desktop for Windows然后在它的设置里打开 WSL Integration指定哪个发行版可以访问 docker 命令。另一条是直接在 WSL 发行版内部安装 Docker Engine当作普通 Linux 服务器那样用。Docker Desktop 的优点是省心图形界面能看容器、看镜像、看日志而且 docker 命令在两个系统里都能用。缺点是常驻内存开销大后台一堆进程。我自己的取舍是日常开发用 Docker Desktop因为它省事如果是纯跑几个容器做后端服务用 WSL 内原生 Engine 更轻。不管走哪条路有一个配置强烈建议打开把容器和镜像的数据放在 WSL 的 ext4 文件系统里不要挂到/mnt/c。Docker 的存储驱动对文件系统特性要求高overlay2 在 9P 挂载上是跑不起来的非要挂载就会出现各种奇怪错误。如果走原生 Engine 这条路因为新版 WSL 支持 systemd启动方式简单了很多。先在/etc/wsl.conf里打开[boot] systemdtrue重启 WSL 之后systemctl就能用了照着常规的 Linux 安装流程装 Docker 即可。5.4 磁盘膨胀与内存占用两个必须管住的指标先说磁盘。WSL2 的虚拟磁盘ext4.vhdx有一个讨厌的特性只增不减。你在里面装了 20GB 的东西再删掉文件大小不会缩回去。跑半年之后 C 盘莫名其妙少了几十 GB多半就是它。查看实际占用在 PowerShell 里wsl --list --verbose再看磁盘文件本身的大小路径在C:\Users\用户名\AppData\Local\Packages\发行版包名\LocalState\ext4.vhdx。压缩回收的方法有几种。较新版本的 WSL 支持直接设置稀疏模式wsl --manage Ubuntu-22.04 --set-sparse true打开稀疏之后删除文件释放的空间会自动归还给系统。老版本就得手动压缩先wsl --shutdown完全关掉然后用 diskpart 的compact vdisk或者用 Hyper-V 的Optimize-VHD命令。手动压缩比较慢几十 GB 要等十几分钟中途不要中断。另一个思路是干脆搬家把发行版移到空间充裕的盘。新版 WSL 可以直接移动wsl --shutdown wsl --manage Ubuntu-22.04 --move D:\wsl\Ubuntu-22.04如果不支持--manage --move就用导出导入的方式wsl --export Ubuntu-22.04 D:\wsl\backup.tar wsl --unregister Ubuntu-22.04 wsl --import Ubuntu-22.04 D:\wsl\Ubuntu-22.04 D:\wsl\backup.tar --version 2--unregister之后默认用户会丢导入完需要重新指定ubuntu2204 config --default-user 你的用户名再说内存。WSL2 默认会拿走主机最多一半内存或者 8GB取较小值跑大项目编译的时候能直接把机器拖卡。限制方式是在用户目录下建一个.wslconfig文件注意路径是C:\Users\用户名\.wslconfig不是 Linux 里的家目录[wsl2] memory8GB processors6 swap4GB localhostForwardingtrue networkingModemirrored [experimental] autoMemoryReclaimgradual sparseVhdtruememory限制最大内存processors限制 CPU 核心数swap设置交换空间。autoMemoryReclaimgradual这个实验特性很有用它让 WSL 在空闲时主动归还内存给 Windows解决了开着 WSL 之后任务管理器里内存一直居高不下的问题。networkingModemirrored是新版才有的网络模式开了之后 WSL 和 Windows 共享网络栈localhost 访问更直接某些场景下比默认 NAT 模式方便得多。改完这个文件要执行wsl --shutdown才生效。.wslconfig里能配的东西远不止这些但上面这几个是对日常体验影响最大的。配置文件本身对格式比较敏感注意段落名必须是[wsl2]和[experimental]键值之间不要加引号单位大小写不敏感但建议统一用GB。最后再提一个日常习惯定期导出备份。WSL 的发行版是可以一条命令打包成 tar 的把备份放在另一个盘上换机器或者重置系统的时候直接导入环境原样恢复比重新配一遍节省几个小时。wsl --export Ubuntu-22.04 D:\backup\ubuntu-$(Get-Date -Format yyyyMMdd).tar我个人在实际操作中的体会是WSL 的坑大部分不在安装环节而在用了一段时间之后。刚装好的时候一切顺畅等你把项目、容器、依赖都堆进去磁盘膨胀、内存不还、跨文件系统卡顿这些问题才会陆续冒出来。所以真正省时间的做法不是出问题再修而是在装完的第一天就把.wslconfig、/etc/wsl.conf、项目存放位置这三件事定下来后面就基本不用再管它了。