不瞒你说,作为一个平时主要用 Windows、但对 Linux 环境又有刚需的人,我一直觉得 WSL 就是“打开开关就能用”的东西。结果这个五一假期,我整整两天都耗在 WSL 上,从安装到配置到各种报错,硬生生把“wsl --install”一条命令能解决的事,折腾成了大型翻车现场。回头想想,这些坑踩得不算冤枉,因为很多问题网上答案零散,搜半天也搜不到点子上。这篇就当是我自己的踩坑日记,把这两天和 WSL 死磕的完整经过、解决思路和一些非常规操作的细节写出来,希望能帮你少走点弯路。
这篇内容主要适合这几类人:想在 Windows 上跑 Linux 环境做开发、学习或者跑 Docker 的朋友;刚接触 WSL 但马上被 403、更新太慢、磁盘膨胀等问题劝退的新手;以及那些已经装了 WSL 但总感觉“能用但不好用”的人。我会尽量把每个坑背后的原因也讲清楚,不只是贴命令。毕竟,光会抄命令,换个场景就抓瞎了。
1. 折腾之前先想明白:WSL 到底是什么,我为什么选它
1.1 WSL 1 和 WSL 2 的差别,选错版本等于白折腾
很多教程直接把 WSL 2 当成默认选项,但如果你不清楚 WSL 1 和 WSL 2 的本质区别,后面遇到问题会很难判断方向。
简单说,WSL 1 更像是一个“翻译层”。它把 Linux 的系统调用转换成 Windows 内核能理解的操作,所以启动快、文件访问直接走 Windows 文件系统,性能也不错。但缺点很明显:不是所有 Linux 程序都能兼容,遇到 Deepin、内核模块、Docker 这类重度依赖 Linux 内核特性的东西,WSL 1 基本就废了。
WSL 2 则改成了轻量级虚拟机方案。它用的是真正的 Linux 内核,跑在一个由 Hyper-V 管理的极简虚拟化环境里。好处是兼容性大幅提升,Docker、CUDA、systemd 都能用;坏处是跨操作系统访问文件时性能会打折,而且虚拟磁盘文件(ext4.vhdx)会不断膨胀,这个坑我后面专门讲。
如果你只是写写脚本、用用 grep 和 ssh,WSL 1 确实够用。但如果你要跑 Docker、装显卡驱动做深度学习、或者需要和 Windows 上的开发工具链深度配合,老老实实上 WSL 2。我自己最终选择了 WSL 2,因为 Docker 和 AI 环境是我绕不开的需求。
1.2 安装前的环境检查,避免在第一步就卡住
我第一天浪费的两个小时,有一半是因为没提前检查环境就急着敲命令。你可以先对照检查这几项:
- Windows 版本:WSL 2 需要 Windows 10 2004 及以上,或者 Windows 11。老系统只支持 WSL 1。
- 虚拟化开关:WSL 2 依赖 CPU 的虚拟化功能,BIOS 里必须开启 Intel VT-x 或 AMD-V。不确定的话,打开任务管理器 -> 性能 -> CPU,看“虚拟化”那一行。
- 系统组件:“适用于 Linux 的 Windows 子系统”和“虚拟机平台”这两个功能都要启用。新版
wsl --install会自动开,但如果你用的是精简版系统,可能不会自动处理。
我在一台精简版 Windows 10 上踩到过一个经典错误:在 PowerShell 里输入wsl --install,结果提示“无法将‘wsl’项识别为 cmdlet”。这说明系统里根本没有 WSL 相关组件,直接跑命令当然没用。这种情况要先手动启用功能,用管理员权限的 PowerShell 执行:
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart执行完重启电脑,再继续后面的安装。提前做这三项检查,能省下大量排查时间。
2. 安装全程记录:从一条命令到一块能用的 Ubuntu
2.1 一条命令装 WSL,我却卡在了 403
正常流程是这样的:管理员权限打开 PowerShell,执行wsl --install,系统会自动启用需要的 Windows 功能、下载 WSL 内核,并安装默认的 Ubuntu 发行版。全程只需要一条命令。
但我在实际操作时,PowerShell 直接给我甩了一句“已禁止(403)”。当时我整个人是懵的:我什么都没干,怎么就被禁止了?
后来查了一圈,403 的常见原因主要是这几类:
- 网络访问微软服务不稳定,CDN 返回了错误状态码。
- 电脑上是企业定制系统,组策略限制了商店或相关服务。
- 某些安全软件或网络优化工具拦截了请求。
解决办法没有银弹,我后来试出来的组合拳是:换一个干净网络环境重试、确保 PowerShell 是以管理员身份运行、把系统区域设置改成“英语(美国)”再重试(这个偏方对部分微软商店相关报错确实有效)。如果还是不行,就绕开命令行,直接打开 Microsoft Store,在里面搜索 Ubuntu 并点击安装,走商店通道。
提示:如果你和我一样,无论如何都摆脱不了 403,不要死磕。直接用 Microsoft Store 或离线安装包安装发行版,效果是一样的,没有必要在一条路上耗太久。
2.2 wsl --update 下载太慢,可以试试 --web-download
装好发行版之后,很多新手会碰到 Docker Desktop 或者某些新特性提示:“Your version of Windows Subsystem for Linux (WSL) is too old. Run wsl --update”。
于是我很听话地执行了wsl --update,然后就开始无尽等待。这个更新包是从微软服务器拉取的,国内网络环境下经常慢到怀疑人生。
这里有一个很实用的小技巧:WSL 支持--web-download参数,可以改成从 GitHub 下载更新包。在某些网络场景下,GitHub 反而比微软服务器更稳更快。命令是:
wsl --update --web-download如果连 GitHub 也慢,那就只能挂机等了。好在 WSL 更新包不算特别大,只要能跑起来,等待时间通常可以忍受。更新完成后,尽量重启一下终端,再继续后面的操作。
2.3 安装 Ubuntu 发行版:选 LTS 版本,别选花里胡哨的版本
wsl --install -d Ubuntu-24.04可以直接指定发行版,这是我更推荐的方式,因为默认版本不一定是你想要的。如果要看有哪些发行版,先执行:
wsl --list --online但这个命令也容易踩“连接超时”的坑。原因和更新慢类似,都是网络访问问题。如果你试了几次都超时,完全不用卡在“看列表”这一步,直接指定你想要的发行版名就行。比如:
wsl --install -d Ubuntu-24.04版本选择上,我建议用长期支持版本(LTS),比如 Ubuntu 22.04 或 Ubuntu 24.04。原因是教程多、软件源稳定、第三方工具兼容性好。我用的是 Ubuntu 24.04,配合 WSL 2 跑得很顺。
安装完成后,第一次启动会让你设置 Linux 用户名和密码,这个用户名会成为 WSL 里的默认用户,相当于 Linux 环境里的管理员(可以免密 sudo,但 Windows 的账户是独立的)。
3. 装完后的体验优化:字体、VSCode 和终端工作流
3.1 让 WSL 里的代码看起来接近 macOS 体验,关键是字体
在 WSL 里写代码,终端字体直接影响视觉疲劳。我试过好几款,最后留下的选择是:CaskaydiaCove Nerd Font 或 JetBrains Mono Nerd Font。这两款都是等宽字体,而且带 Nerd Font 图标补丁,终端里能正常显示特殊符号和文件类型图标,观感上非常接近 macOS 上那种清爽效果。
如果用的是 Windows Terminal,按Ctrl + ,打开设置,修改配置文件里的font.face字段即可:
{ "profiles": { "defaults": { "font": { "face": "CaskaydiaCove Nerd Font", "size": 14 } } } }字体文件下载后,右键选择“为所有用户安装”或“安装”,再回到 Windows Terminal 重新加载,就能生效。个人建议字体大小选 14 或 15,长时间盯屏幕不会太累。
3.2 VSCode + WSL:用 code . 直接在 Windows 里打开 Linux 环境
VSCode 对 WSL 的支持是我选择这条路的另一个重要原因。装好 Remote Development 扩展包后,在 WSL 终端里进入某个项目目录,执行:
code .VSCode 会自动以“WSL 模式”启动,左下角显示WSL: Ubuntu-24.04,在这个窗口里打开的终端、运行的调试任务、安装的扩展,全都是 Linux 环境下的。
我第一次用的时候踩了一个小坑:在 Windows 侧装的扩展,并不能直接在 WSL 模式下生效。比如你在 Windows 里装了 Python 扩展,但进入 WSL 模式后,VSCode 会提示你“在 WSL 中安装扩展”。跟着提示点一下就好,它会在 Linux 侧重新装一份。这不算 bug,这是 WSL 模式的核心逻辑:Windows 侧的进程服务和 Linux 侧的开发环境是隔离的,只有通过 VSCode 的统一界面才能无缝衔接。
注意:如果你的项目文件放在 Windows 路径(比如
/mnt/c/Users/...),运行起来会明显比在 Linux 文件系统里慢,尤其是 Node.js 和 Python 这种小文件读写频繁的项目。最稳的做法是把项目克隆到 WSL 的 home 目录下,比如~/projects,然后再用code .打开。
3.3 wsl.conf 定制:让 WSL 按我的习惯工作
WSL 里有一个全局配置文件/etc/wsl.conf,可以设置很多东西。我最常用的配置长这样:
[user] default=你的用户名 [boot] systemd=true [network] generateResolvConf = false[user] default用来设置默认登录用户,如果你不小心跑成了 root,可以靠这个改回来。[boot] systemd=true非常重要。有了 systemd,你才能在 WSL 里用systemctl enable管理服务,Docker、SSH 这些服务装起来会更顺手。[network] generateResolvConf = false是当 DNS 出问题时的应急开关。如果你遇到“无法解析域名”的报错,可以在 WSL 里手动写/etc/resolv.conf,指定公共 DNS,然后关闭自动生成。
改完配置后,需要重启 WSL 才生效。重启指令是在 Windows PowerShell 里执行的:
wsl --shutdown然后重新打开 WSL 终端。
4. 踩坑实录:这两天的翻车现场,值得记进小本本
4.1 ext4.vhdx 越用越大,删了文件空间也没释放
这是我第一天遇到的最坑的问题。我在 WSL 里解压了十几 GB 的模型数据和 Python 包,后来删掉一部分,结果 Windows 的 C 盘剩余空间一点没涨。一开始我以为是删除没成功,后来才发现是 WSL 2 的虚拟磁盘文件在作怪。
WSL 2 把整个 Linux 文件系统放在一个动态扩展的虚拟磁盘里,路径一般在:
C:\Users\你的用户名\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu24.04*\LocalState\ext4.vhdx
这个 vhdx 的特点是只增不减。文件删了,Linux 侧空间释放了,但虚拟磁盘文件本身不会自动缩小。解决方法是手动压缩:
wsl --shutdown然后打开 diskpart:
diskpart进入 diskpart 后依次执行:
select vdisk file="C:\Users\你的用户名\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu24.04\LocalState\ext4.vhdx" attach vdisk readonly compact vdisk detach vdisk exit压缩过程视磁盘大小可能需要几分钟,结束后 C 盘空间就回来了。另外,新版 WSL 还支持把发行版设为稀疏模式(sparse),让磁盘空间可自动回收,可以试试:
wsl --manage Ubuntu-24.04 --set-sparse true这两招我现在是定期组合使用,再也没被磁盘膨胀困扰过。
4.2 “Your version of WSL is too old” 这句报错怎么破
这个报错我是在启动 Docker Desktop 时遇到的。原话大概是:“Your version of Windows Subsystem for Linux (WSL) is too old. Run wsl --update”。我第一反应是执行wsl --update,但网络不给力,跑了半天没动静。
后来换了wsl --update --web-download才成功把 WSL 内核更新到较新的版本。更新完后,需要完全退出 Docker Desktop,执行wsl --shutdown再重新打开 Docker Desktop,让后端进程用上新的内核。
如果更新之后依然报这个错,可以检查一下你是否用了“应用商店版 WSL”和“系统内置 WSL”混用的情况。有些环境里存在两个 WSL:一个来自 Windows 系统组件,一个来自 Microsoft Store。wsl --update可能只更新了其中一个,导致版本不一致。稳妥的方案是把商店版 WSL 升级到最新,同时关闭旧版系统组件(或反过来,统一使用商店版)。
4.3 wsl --list --online 连接超时,怎么选安装版本
这个坑我前面提过。wsl --list --online的目的是查看微软商店提供了哪些可安装的 Linux 发行版,但网络不好时大概率超时。
我当时的做法是:直接查官方文档,确认了想要的发行版名称(比如Ubuntu-24.04、Debian、kalilinux),然后跳过 list 命令,直接执行:
wsl --install -d Ubuntu-24.04因为安装发行版时的下载服务器走的是商店通道,只要商店能访问,不依赖 list 命令的连通性。如果你要装的发行版比较特殊,商店列表里看不到,也可以下载离线安装包(.appx或.msixbundle),然后用 PowerShell 执行:
Add-AppxPackage -Path "下载好的安装包路径"离线包安装完成后,Launch 一下开始菜单里的新图标,按提示设置用户名密码即可。这是绕过所有在线列表问题的终极方案。
4.4 Docker Desktop 提示 “WSL is unresponsive”,到底是谁的锅
这个坑我是在第二天下午踩到的。Docker Desktop 启动后弹了个窗:“Docker Desktop - WSL is unresponsive”,看起来像是整个后端卡死了。
排查过程大概是这样的:
- 先试试
wsl --shutdown,重启 WSL 后端。 - 再执行
wsl --update --web-download,确保内核是新的。 - 重启 Docker Desktop,看是否恢复。
- 如果还不行,
wsl -l -v看一下有没有docker-desktop这个发行版。它是 Docker Desktop 自动创建的 WSL 后端发行版,偶尔会状态异常。
最后一步是重置 Docker 的 WSL 后端:
wsl --unregister docker-desktop然后重启 Docker Desktop,它会自动重新创建后端。这个操作一般不会影响你的容器数据和镜像,因为它们通常存在另一个叫docker-desktop-data的发行版里。但为了安心,操作前最好确认一下自己的容器数据有没有重要内容,有条件的用docker save导出镜像再操作。
4.5 “卸载 WSL 不干净”其实是没有分清发行版和 WSL 本体
很多人在网上问“WSL 怎么卸载干净”,其实问题出在概念混淆。你需要区分两件事:卸载某个发行版,和卸载 WSL 系统组件。
只卸发行版的话,不要直接删开始菜单里的 Ubuntu 图标,那是卸载不干净的。正确操作是:
wsl --shutdown wsl --unregister Ubuntu-24.04--unregister会把这个发行版从 WSL 的管理列表里移除,并删除它的虚拟磁盘文件,相当于完整的删除。如果你还想保留文件,可以用wsl --export先导出备份。
如果要彻底移除 WSL 组件本身,需要在控制面板的“启用或关闭 Windows 功能”里关闭“适用于 Linux 的 Windows 子系统”和“虚拟机平台”,或者用 PowerShell 指令:
dism.exe /online /disable-feature /featurename:Microsoft-Windows-Subsystem-Linux /norestart dism.exe /online /disable-feature /featurename:VirtualMachinePlatform /norestart关闭后再重启,WSL 才算是从系统里彻底清理干净了。
5. 进阶玩法:Docker、CUDA、binwalk,以及和 AI 编码工具的配合
5.1 在 WSL 里装 Docker,比想象中简单
WSL 2 兼容 Docker,有两种常见路线:装 Docker Desktop,或直接在 WSL 里安装 Docker 引擎。我一开始用 Docker Desktop,图的是图形化界面方便管理;踩过“WSL is unresponsive”的坑之后,我开始转向在 WSL 里直接装 Docker CE,更清爽,也更容易排查问题。
在 Ubuntu 里直接安装 Docker 的官方源比较复杂,对新手来说最简单的做法是:
sudo apt update sudo apt install docker.io然后启动服务:
sudo systemctl enable --now docker前提是你在/etc/wsl.conf里开启了systemd=true。如果没开 systemd,也可以手动启动:
sudo service docker start跑一个测试容器验证:
docker run hello-world能看到 “Hello from Docker!” 就说明环境没问题。对于我这种需要频繁测试环境的人来说,直接在 WSL 里装 Docker 比 Docker Desktop 轻量得多,内存占用也少。
5.2 WSL 2 里直接用 CUDA,深度学习不用双系统了
很多做 AI 相关开发的朋友会关心 WSL 能不能用 GPU。答案是能,WSL 2 支持 GPU 直通,只要 Windows 侧安装了支持 WSL 的 NVIDIA 显卡驱动,WSL 内部就可以直接调用。
先验证 GPU 是否可见:
nvidia-smi如果能看到显卡信息,说明直通成功。然后安装 CUDA Toolkit,官网提供针对 WSL-Ubuntu 的安装源,添加源之后:
sudo apt install cuda-toolkit装好后用nvcc --version验证。实际体验下来,在 WSL 里训练中小规模的深度学习模型是没问题的,TensorFlow 和 PyTorch 都能正常跑 GPU 版本。但如果是大规模多卡训练,我还是建议用真正的 Linux 服务器或双系统——WSL 的虚拟化层还是会有一定开销,多卡场景下尤其明显。
5.3 顺手用 binwalk 分析固件,WSL 比 Windows 原生方便太多
我平时偶尔会接触嵌入式相关的学习内容,binwalk 是一个专门用来分析固件镜像、提取文件系统的工具。在 Windows 里折腾这种工具非常痛苦,但在 WSL 里只需要一条命令:
sudo apt install binwalk用法很简单:
binwalk firmware.bin这会扫描固件里的文件签名。想直接把里面的文件系统提取出来,就加上-e:
binwalk -e firmware.bin它会生成一个_firmware.bin.extracted目录,里面就是提取出来的内容。说实话,如果没有 WSL,我大概率不会在 Windows 原生环境里碰这种工具。如果你也是做安全分析、嵌入式开发或者 CTF 的,WSL 这类场景的价值非常大。
提示:binwalk 属于分析工具,只建议用在自己手上的设备固件、开源固件或学习素材中,不要反向拆解未经授权的商业固件,避免踩到合规风险。
5.4 在 WSL 里接入 Codex CLI,终端 AI 编程助手
最近开源社区很热的 Codex CLI(OpenAI 推出的终端编程助手)也可以跑在 WSL 里。安装方式很直接,只要 WSL 里配置好了 Node.js 环境:
npm install -g @openai/codex然后在项目目录下执行:
codex它会变成一个对话式的终端助手,可以帮你写代码、改 bug、解释项目结构。我在 WSL 里配合 VSCode 的 WSL 模式使用,体验还挺顺的:终端里问问题,VSCode 里看代码改动,不需要来回切换窗口。
不过要注意,Codex CLI 需要配置 API Key,而且会消耗 API 额度。如果你只是偶尔问几个问题,成本可以忽略;如果让它帮你批量改代码,还是要留意用量。
另外提醒一下,这类终端 AI 工具依赖 Node.js 的版本,建议在 WSL 里用nvm管理 Node.js 版本,避免系统包管理器装的 Node 版本过旧导致启动报错。
关于 WSL 目录访问和日常习惯,再顺手记两笔
很多新手会疑惑 WSL 里的“下载目录”到底对应 Windows 哪里。其实很简单,WSL 自己有一套独立的文件系统,根目录是/,Linux 下的~/Downloads是 WSL 内部目录;而 Windows 里的C:\Users\你的用户名\Downloads可以通过/mnt/c/Users/你的用户名/Downloads访问。两边是互通的,但跨文件系统读写性能会降低,所以下载大文件时,尽量让目标路径待在同一个文件系统里。
我现在养成的习惯是:下载东西用 WSL 内部目录,需要交给 Windows 软件处理时才放到/mnt/c下。如果你发现 WSL 里操作某个 Windows 目录的文件特别慢,大概率就是这个原因。
最后再分享一个我在折腾过程中觉得最值回票价的习惯:每次环境稳定后,用wsl --export做一次备份。哪天系统被我搞坏了,就用wsl --import快速恢复。
wsl --shutdown wsl --export Ubuntu-24.04 D:\wsl-backup\ubuntu-backup.tar wsl --unregister Ubuntu-24.04 wsl --import Ubuntu-24.04 D:\wsl\Ubuntu .\ubuntu-backup.tar --version 2注意--import之后默认用户可能会变成 root,需要在/etc/wsl.conf里重新设置[user] default。这个备份习惯帮我绕过了好几次“环境搞崩只能重装”的悲剧。毕竟和 WSL 死磕这两天,最大的收获不是每个命令怎么敲,而是知道出了问题该往哪个方向排查,以及怎么在搞崩之后体面地收场。