说个真实情况,我最近帮朋友装WSL,连着踩了好几个坑:wsl --install卡在“正在下载”半天不动,wsl --update跑到 40% 就纹丝不动,wsl --list --online直接报“解析失败”。你要是也正在被这几个问题折磨,那这篇就是给你写的。
WSL(Windows Subsystem for Linux)是 Windows 上跑 Linux 环境的官方方案,对于做开发、运维、学 Linux 的人来说基本是刚需。它能让你在 Windows 里直接开一个真正的 Ubuntu 终端,跑 Docker、写 Shell 脚本、编译 C 代码、用 conda 都行,而且不需要装虚拟机,启动速度比 VMware 快得多。这篇博文适合所有在 Windows 上折腾 WSL 的人,尤其是下载慢、更新失败、发行版列表加载不出来这几类问题的受害者。
先给我的结论:在网络链路不稳定的情况下,官方默认的下载源经常连不上,解决办法是换国内源、手动下载发行版包,或者用离线方式安装。下面我把每一步拆开讲清楚。
1. 内容整体设计与思路拆解
1.1 先搞清楚 WSL 的安装链路由哪些环节组成
wsl --install这条命令看似一键完成,实际上它内部做了四件事:把 WSL 的核心运行时(也就是 WSL2 的虚拟化平台组件)拷贝到系统里;从微软官网下载并注册“WSL 内核更新包”;获取当前可用的 Linux 发行版列表;再从微软的发行版分发服务器下载你指定的 Linux 发行版并安装。
这四个环节里,任何一个被网络卡住,整体进度就会一直停在“正在下载”或者干脆报超时。很多人在这一步反复重试,结果只是反复触发下载流程,十分钟过去了还是老样子。
这就像你去快递站取一个大箱子,箱子从分拣中心运到站里要过几个节点,中间任何一个节点堵了,你在取件窗口就永远拿不到货。wsl --install的“取件窗口”就是 PowerShell 或终端窗口,而它背后依赖的分发链路恰恰是最容易出问题的地方。
1.2 为什么会慢:不是电脑性能问题,是网络链路问题
你电脑的 CPU、硬盘都没毛病,WSL 安装包本身体积也不大(Ubuntu 大约几百 MB),但国内网络访问微软分发服务器、访问 GitHub 上的更新清单时,经常出现 TCP 连接被重置、超时、路由跳数过多的情况。这就是为什么同样的命令,有的人 3 分钟装完,有的人挂半小时连进度条都没动。
所以我的核心思路是:不让安装器走它默认的“长链路”,而是手动给它换一条更短的路径——把下载源切到国内高校或云厂商的镜像站,或者绕过在线下载,直接用本地安装包完成部署。
2. 核心细节解析与实操要点
2.1 wsl --install 慢:先判断卡在哪个环节
遇到wsl --install慢,别急着反复重跑命令。先开一个 PowerShell,执行下面这条命令,看看系统里有没有装过 WSL 相关组件:
wsl --status如果返回“默认版本:2”或者“默认分发:”之类的信息,说明 WSL 的核心框架已经装过了,只是缺一个发行版;如果返回“未安装适用于 Linux 的 Windows 子系统”,说明整个框架都没装起来。
区分这两种情况很有用:框架缺失时,你需要优先处理内核组件的下载问题;框架已装时,你只需要单独装某个发行版,可以完全不走在线分发列表,直接手动下载发行版的 appx 包来安装,绕开最慢的环节。
2.2 手动下载 Ubuntu 发行版包:最稳妥的一招
我实测下来最稳定的一种处理方式,是直接去微软的官方中文站点下载 WSL 发行版安装包。微软的发行版包是 .appx 或 .msixbundle 格式的文件,下载后双击或者用命令行添加就能完成安装,不依赖wsl --install的在线分发功能。
具体步骤如下:先打开你常用的浏览器,访问微软的文档中心搜索“WSL 手动安装”,找到“适用于 WSL 的 Linux 发行版下载”部分,里面列出了 Ubuntu、Debian、Kali Linux 等多个发行版的下载链接。注意优先选择 withWSL 版本或者支持 WSL2 的版本。
下载完成后,把文件放到一个不容易被误删的目录,比如D:\WSL\,然后以管理员身份打开 PowerShell,进入文件所在目录:
cd D:\WSL Add-AppxPackage .\Ubuntu_2204.1.7.0_x64.appx等待命令结束后,直接运行 Ubuntu:
ubuntu.exe首次启动会让你设置 Linux 用户名和密码,设置完成后就能正常使用了。这种方法的好处是下载时用浏览器走的是常规 HTTP 通道,不容易因为命令行下载器本身的握手方式导致连接被重置。
我在实际测试中发现,用浏览器直接下载这个包,速度通常能稳定在几 MB/s 到十几 MB/s,比命令行里卡着不动的情况好太多。要是浏览器也慢,那就换下面 2.3 的镜像源思路。
2.3 wsl --update 更新慢:手动下载内核更新包去替换
WSL2 需要单独的 Linux 内核组件,wsl --update就是去拉取这个内核更新包。它的下载地址同样在微软服务器上,国内访问时常抽风。
如果你运行wsl --update发现进度条不动,可以直接去微软的 WSL 内核更新包页面,手动下载“WSL2 Linux 内核更新包 x64 计算机”,这是一个 .msi 文件,下载后直接双击运行。安装完成后关掉所有终端,重新打开一个,再执行:
wsl --version看到内核版本号出现就说明更新成功了。
需要注意的是,有些机器上wsl --update会提示“已禁止(403)”,这在很大程度上是网络策略或代理设置导致请求被服务端拒绝。这种情况下直接用 .msi 包更新是最省事的路径,不用跟命令行较劲。
2.4 内核更新包和发行版包的区别
一定要分清楚:内核更新包是给 WSL2 的虚拟机直接用的一块“固件”,负责让 Windows 的虚拟化平台能跑 Linux 内核;发行版包则是你实际用的 Ubuntu 或 Debian 系统本身。两个都缺的话,或者更新卡壳,都是各自独立处理的,别混在一起排查。
很多人遇到 WSL 进不去、报内核太旧之类的错误,第一反应是重装 Ubuntu,但实际可能是内核更新包没装上。新版 WSL 要求内核版本不能太低,否则会提示 “Your version of Windows Subsystem for Linux (WSL) is too old”,这时候单独装一次内核更新包往往就好了。
3. 实操过程与核心环节实现
3.1 解决 wsl --list --online 解析失败
wsl --list --online用来查看当前可安装的发行版列表。报“解析失败”或者说“无法从 GitHub 获取列表”的时候,根源其实在于这条命令要去 GitHub 的一个仓库里拉取发行版清单,而那条网络路径经常不通。
我建议的做法是绕过这个列表命令。你需要什么发行版,直接按 2.2 的方式下载对应包即可。如果你就是想看看官方提供了哪些发行版,可以手动访问 GitHub 上 microsoft/WSL 仓库里的发行版列表文档,但那个页面也不一定稳定。所以现实一点的做法就是:明确目标,直接下载,别再依赖列表命令。
这里也提供一个判断技巧:如果wsl --list --online报错,但wsl --status正常,说明核心框架没问题,缺的是“商店”的连接能力,而不是 WSL 本身。你完全可以忽略这个报错,继续往下走。
3.2 升级 WSL1 到 WSL2:版本切换的注意事项
有不少人电脑上是 WSL1,想升级到 WSL2。升级条件有三个:Windows 10 版本在 2004 以上(内部版本 19041 以上);BIOS 里开启虚拟化;内核更新包已安装。
在 PowerShell 管理员模式里执行以下命令切换到 WSL2:
wsl --set-version Ubuntu-22.04 2如果你不知道发行版叫什么,先运行wsl --list查看。切换过程需要一两分钟,期间会提示“正在进行转换”,完成后再执行wsl --list --verbose看 VERSION 列是否变成了 2。
这里有个坑:有些电脑明明支持虚拟化,但 Windows 的“虚拟机平台”功能没开,转换会失败。你需要去“启用或关闭 Windows 功能”里勾选“虚拟机平台”和“适用于 Linux 的 Windows 子系统”,重启后再执行转换命令。
3.3 WSL 默认存储位置的迁移:释放 C 盘空间
WSL 的发行版默认安装在 C 盘用户目录下,时间一长,像 Docker 镜像、conda 环境、编译中间文件很容易占掉几十 GB。我之前就遇到 C 盘直接爆红的情况,后来把整个发行版迁到了 D 盘。
核心操作分四步。第一步,在 PowerShell 里导出当前的发行版为 tar 包:
wsl --export Ubuntu-22.04 D:\WSL\ubuntu2204.tar第二步,注销当前的发行版:
wsl --unregister Ubuntu-22.04注意,--unregister会删除该发行版的全部数据,所以导出包的步骤一定不能省略。第三步,重新导入:
wsl --import Ubuntu-22.04 D:\WSL\Ubuntu D:\WSL\ubuntu2204.tar --version 2第四步,启动后如果发现当前用户变成了 root,需要在发行版里重新设置默认用户:
ubuntu2204.exe config --default-user yourname整个过程大概需要十几分钟到半小时,取决于数据量大小,但迁移完成之后 C 盘能释放出可观的占用空间。
3.4 配置 .wslconfig 限制内存和 CPU,避免卡死
WSL2 默认会占用宿主机相当一部分内存资源,默认值是最多占物理内存的 50% 甚至更多。如果你机器本身内存不大,或者觉得 WSL 抢了 Windows 的资源,可以创建一个配置文件来限制它。
在C:\Users\你的用户名\.wslconfig文件里写入以下内容:
[wsl2] memory=4GB processors=4 swap=8GB localhostForwarding=true保存后执行:
wsl --shutdown再重新打开 WSL 就会生效。memory是 WSL2 可用的最大内存,processors是分配给它的 CPU 核数,swap是交换空间大小。这个配置对经常跑 Docker 或者大型编译任务的场景特别有用,防止 WSL 把整机资源吃满导致卡死。
3.5 在 VSCode 中使用 WSL:开发体验的关键一步
装好 WSL 不只是为了在终端里敲命令,更常见的使用姿势是用 VSCode 连接 WSL 里的项目目录。VSCode 官方有“Remote - WSL”扩展,装好之后,在 WSL 终端里进入项目目录,执行:
code .VSCode 就会自动以 WSL 模式打开当前目录。这个模式下,你看到的文件是 Linux 里的文件,终端也是 Linux 环境,但编辑器本身还是用 Windows 的图形界面,体验非常顺滑。加上 WSL 里可以直接跑 Ubuntu 下的编译和调试工具链,我日常的 Python、C++ 开发都在这套环境里完成。
一个小建议:WSL 里的字体设置会影响代码阅读体验,如果你追求接近 macOS 的视觉效果,可以在 VSCode 的设置里把终端字体设为 “Cascadia Mono” 或 “JetBrains Mono”,这两个字体在终端里显示中文和代码的观感都很舒服。
3.6 在 WSL 里安装 Docker:轻量开发环境搭建
WSL2 天然支持 Docker,这是很多人装 WSL 的直接原因。在 WSL 的 Ubuntu 里安装 Docker 的方式和普通 Ubuntu 服务器一样,官方推荐的联网安装方式在国内同样可能遇到慢的问题。
我的做法是把 apt 源先换成国内镜像源,再安装 Docker。具体步骤是修改/etc/apt/sources.list,把官方源替换成清华或阿里云的镜像源,然后执行:
sudo apt update sudo apt install docker.ioWSL2 里的 Docker 默认需要 systemd 支持,新版 Ubuntu 一般已经内置了 systemd,安装完成后执行:
sudo systemctl start docker sudo systemctl enable docker就能正常使用docker ps、docker run这些命令了。
4. 常见问题与排查技巧实录
4.1 问题速查表
| 现象 | 可能原因 | 解决办法 |
|---|---|---|
| wsl --install 卡住不动 | 微软分发服务器连接超时 | 换浏览器手动下载 appx 安装包 |
| wsl --update 进度条不动或 403 | 内核更新包下载请求被拒 | 下载 .msi 内核包手动安装 |
| wsl --list --online 解析失败 | GitHub 列表拉取不通 | 跳过列表,直接指定发行版下载 |
| 系统提示 WSL 版本太旧 | 内核更新包没装 | 手动安装 Linux 内核更新包 |
| 转换到 WSL2 失败 | 虚拟机平台功能未开启 | 勾选 Windows 功能并重启 |
| WSL 占内存太多 | 默认资源上限过高 | 配置 .wslconfig 限制内存和 CPU |
| C 盘空间爆满 | 发行版默认装在 C 盘 | 使用 wsl --export/--import 迁移 |
| 安装时报错“已禁止(403)” | 网络策略或代理干扰 | 换浏览器下载安装包离线安装 |
| WSL 里 apt 下载慢 | Ubuntu 默认源速度不佳 | 把 apt 源切换到国内镜像 |
4.2 实测下来的几条避坑经验
第一,安装和更新 WSL 时不要同时开太多下载任务,比如一边装 WSL 一边在 Steam 下载游戏,很容易把本就有限的带宽资源再次压榨,导致超时概率明显提升。
第二,错误提示“已禁止(403)”不一定是你的操作有问题,我之前排查过好几台机器,共同点是 Windows 系统里的网络代理设置干扰了命令行工具的请求头,导致服务器直接拦截。如果你那边有类似代理工具在跑,建议先暂时关掉,或者用系统自带的“恢复默认网络设置”功能重置网络栈再试。
第三,如果你的系统是 Windows Server 2016 或更老的版本,WSL 支持很不完整,很多命令根本不存在。这里建议优先升级到 Windows 10 2004 以上版本,别在老系统上浪费时间。
第四,需要特别留意:WSL 安装完之后尽量少用管理员权限来启动日常开发。因为管理员身份跑 Ubuntu 会导致文件权限错乱,比如你在 Windows 里用普通编辑器打开 WSL 目录里的文件,可能会没有写权限。正确姿势是:普通用户的终端里进入 WSL,用 sudo 执行需要提升权限的命令。
第五,Docker 在 WSL 里跑不起来时,先检查/etc/wsl.conf里有没有[boot]段支持 systemd。新版本 Ubuntu 默认启用 systemd,但老版本或者从 WSL1 切到 WSL2 的发行版不一定默认开启,需要手动配置。
4.3 关于“在 WSL 中写代码的字体推荐”的补充
有朋友问过我,WSL 终端里写代码推荐什么字体能接近 macOS 的体验。我实测下来,Cascadia Code 和 JetBrains Mono 都不错。Cascadia Code 是微软官方终端默认字体,支持连字,在中文 Windows 下显示很干净;JetBrains Mono 在做大括号、箭头等符号时辨识度更高,适合长时间盯代码。
配置方式很简单,在 Windows Terminal 设置里找到“配置文件”里的“外观”,把字体改成你选的字体即可。如果 Windows 里没有安装字体,先下载字体文件,右键选择“为所有用户安装”,然后重启 Windows Terminal 就能在字体列表里看到了。
4.4 处理 WSL 网络和 DNS 问题
WSL2 的网络模式是 NAT 模式,有时候会出现解析域名失败的问题。常见原因是/etc/resolv.conf里的 DNS 服务器地址不对,或者 Windows 防火墙拦截了 WSL 的 UDP 请求。
快速验证方式是在 WSL 里执行:
cat /etc/resolv.conf如果看到 nameserver 是 127.0.0.1 或一个不可达的地址,可以临时手动改成公共 DNS:
sudo sh -c 'echo "nameserver 223.5.5.5" > /etc/resolv.conf'不过这个配置重启 WSL 后可能被重置,长期解决办法是编辑/etc/wsl.conf,加入:
[network] generateResolvConf = false然后手动管理/etc/resolv.conf。改完之后记得在 Windows 里执行wsl --shutdown重启 WSL。
5. 我的最终实操建议
在 Windows 上把 WSL 玩顺,核心思路和我在前面反复提到的一致:别和官方默认的网络链路死磕。能用浏览器下载的就用浏览器下载,能换镜像源的就换镜像源,能离线装的就离线装。
我现在的安装流程已经固定成了这样:先看系统支不支持虚拟化,再手动下载发行版 appx 包,用 Add-AppxPackage 安装,保险起见再下一个内核更新包 .msi 装上,最后进系统配置一次 apt 镜像源、配好 .wslconfig 和 /etc/wsl.conf,整个环境跑起来之后非常稳定,不再出现三天两头更新失败或者启动报错的情况。
最后分享一个小技巧:如果你需要在多台电脑上装 WSL,提前把 appx 安装包和内核更新包 .msi 文件存到 U 盘或者网盘里,后面新电脑配置时直接离线安装,速度最快,还不用看网络脸色。我自己就是这样干的,省去了大量重复等待的时间。