2. 基础概念与命令速查:先搞懂WSL到底在管什么
WSL(Windows Subsystem for Linux)对于经常在 Windows 和 Linux 工具链之间来回切换的人来说,不是玩具,而是一台可以随时创建、销毁、迁移的轻量开发机。尤其是这两年 WSL 从原来的“实验性功能”变成 Windows 的正式组件之后,整套管理命令已经非常完善,但大多数人只用了其中两三条:装系统、开终端、关终端。
这篇文章不打算讲那些装完就忘的基础操作,而是把 WSL 最常用的一批管理命令系统性地过一遍。从安装、多发行版管理、启停控制、导入导出、资源限制,到高频报错排查,基本覆盖我日常工作中每天都会碰到的场景。适合刚接触 WSL 的新手做一次完整扫盲,也适合已经用了一段时间但想把手里的 WSL 整理得更干净的老手。
先说一个经常被忽略的点:WSL 管理命令分为两类,一类在 Windows 侧执行,就是 wsl.exe 这个程序;另一类在 Linux 侧执行,比如 systemctl、dmesg、free。这篇文章以 Windows 侧的 wsl.exe 命令为主,因为“管理 WSL”这件事本身就是 Windows 侧的工作,Linux 侧的命令只是在发行版内部做状态检查的时候配合使用。
2.1 版本与运行机制:为什么管理命令如此重要
理解管理命令之前,得先知道 WSL 1 和 WSL 2 的区别。WSL 1 是一个系统调用翻译层,不包含真正的 Linux 内核,兼容性有限,很多涉及内核模块、Docker、GPU 的场景跑不了。WSL 2 则是一个轻量级虚拟机,有完整 Linux 内核,兼容性接近原生。
这个差异直接决定了管理命令的行为。比如 wsl --shutdown 这个命令,在 WSL 2 下会关闭整个轻量虚拟机,所有发行版都会停止;在 WSL 1 下就没有这个语义,因为 WSL 1 不是一个虚拟机。再比如 wsl --set-version <发行版> 2,用来把某个发行版从 WSL 1 升级到 WSL 2,如果机器不支持虚拟化或没有开启相应 Windows 功能,就会报错。
查看当前所有发行版的状态,最常用的命令是:
powershell复制wsl -l -v
输出内容类似这样:
code复制 NAME STATE VERSION
* Ubuntu-22.04 Running 2
Debian Stopped 1
第一列的星号表示默认发行版,最后一列就是版本号。很多管理问题都出在“版本不一致”上,所以拿到一台新机器,我第一件事永远是跑这条命令,先看清楚当前环境到底是什么状态。
2.2 核心管理命令速查表
这里先把最常用的命令列一个表,后面每个章节再展开说应用场景。这张表建议收藏,日常遇到问题先翻一眼,比自己盲试快得多。
| 命令 | 作用 | 典型使用场景 |
|---|---|---|
wsl -l -v |
列出所有发行版及运行状态 | 查看当前环境,确认默认发行版 |
wsl --status |
显示 WSL 整体状态 | 查看默认版本、内核版本 |
wsl --version |
查看 WSL 程序自身版本 | 确认是否需要更新 |
wsl --install -d Ubuntu-22.04 |
安装指定发行版 | 新机器上装系统 |
wsl --set-default <发行版> |
设置默认发行版 | 多个发行版并存时切换 |
wsl --set-version <发行版> 2 |
切换 WSL 1/2 版本 | 从 WSL 1 迁移到 WSL 2 |
wsl --terminate <发行版> |
停止指定发行版 | 某个发行版卡死时强制结束 |
wsl --shutdown |
关闭整个 WSL 虚拟机 | 修改 .wslconfig 后重启生效 |
wsl --export <发行版> <文件> |
导出发行版为 tar 文件 | 备份、迁移到其他机器 |
wsl --import <发行版> <目录> <文件> |
导入 tar 文件为发行版 | 恢复备份、离线安装 |
wsl --unregister <发行版> |
注销并删除发行版 | 清理环境、重装系统 |
这条命令 wsl -d <发行版> -- <命令> 不是管理命令,但非常常用,用来在 Windows 侧直接调用某个发行版里的 Linux 命令,后面专门讲互操作时再展开。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
3. 从零安装到多发行版编排:安装与管理实战
3.1 一条命令装好 WSL,但要注意参数细节
现在新版 Windows 上安装 WSL 已经非常简单,管理员权限的 PowerShell 里跑一条:
powershell复制wsl --install
默认会安装 WSL 2 和一个 Ubuntu 发行版。实际使用中我更喜欢指定发行版,避免安装默认版本后还要再折腾:
powershell复制wsl --install -d Ubuntu-22.04
如果不确定有哪些发行版可选,可以先跑:
powershell复制wsl --list --online
会显示可用的发行版列表。需要注意,wsl --install 在部分精简版 Windows 上可能提示缺少功能组件,这时需要先手动启用“适用于 Linux 的 Windows 子系统”和“虚拟机平台”这两个 Windows 功能,然后重启再执行安装。查看功能是否启用的命令是:
powershell复制dism.exe /online /get-featureinfo /featurename:Microsoft-Windows-Subsystem-Linux
还有一个经常被人忽略的参数 --no-distribution,作用是不安装任何发行版,只安装 WSL 核心框架。这个参数适合离线包方案,后面第二小节会用到。
3.2 安装过程卡在下载的实战解法
wsl --install 执行后,经常有人遇到下载停滞、进度条不走的情况。这通常不是命令写错了,而是发行版包比较大,下载速度受本地网络环境影响,卡在 downloading 阶段是高频问题。
我的处理办法分三步,按优先级尝试。
第一步,先取消当前安装,执行一次内核更新,把它切换到直连下载通道:
powershell复制wsl --update --web-download
这个参数的作用是强制 WSL 从微软的在线分发通道直接下载最新组件,而不是走 Windows Update 的推送流程。有时候 Windows Update 的更新链路本身就慢,换一个下载通道效果立竿见影。
第二步,使用 --no-distribution 先装 WSL 本体,然后把发行版作为独立组件单独安装:
powershell复制wsl --install --no-distribution
装完本体后,再单独安装发行版,可以避免两个大文件同时下载互相挤占带宽。
第三步,如果还是慢,就换离线方案。去微软官网下载 WSL 的离线安装包,或者直接下载发行版的 Appx 包,然后用 Add-AppxPackage 命令导入。发行版的 Appx 包也可以从第三方镜像站获取,但这里建议大家优先用微软官方渠道,安全性和兼容性都有保障。
还有一个容易踩的坑:安装过程中最好不要反复中断。wsl --install 被中断后,Windows 功能可能已经启用一半,发行版却只下载了一部分,下次再装时会报各种奇怪错误。如果已经出现这种情况,先执行:
powershell复制wsl --shutdown
然后重新执行安装命令。如果反复失败,检查一下 C:\Users\<用户名>\AppData\Local\Packages 下是否有残留的发行版目录,有的话需要清理干净再装。
3.3 多发行版并存时的切换与管理
WSL 真正方便的地方在于多发行版并存。我自己的机器上同时装了 Ubuntu 22.04 和 Debian 12,一个跑日常开发,一个用来做软件包兼容性测试。
多发行版安装完成后,用 wsl -l -v 可以看到所有发行版。默认执行 wsl 时进入的发行版,用这条命令切换:
powershell复制wsl --set-default Ubuntu-22.04
如果只是临时想在某个发行版里执行一条命令,不需要切换默认设置,直接加 -d 参数:
powershell复制wsl -d Debian -- uname -a
这条命令的意思是:这次执行仅针对 Debian 发行版,进去后运行 uname -a,运行完退出。这个模式非常适合在批处理脚本里管理多个发行版,比如同时更新所有发行版时,只需要写两行命令挨个执行即可。
4. 发行版生命周期管理:从注册到注销
4.1 状态检查与启停控制
这一章节的内容是 WSL 管理命令里最核心的部分。先说状态检查。
wsl -l -v 能列出所有发行版和当前状态,但很多情况下你还需要知道 WSL 整体的运行状态。wsl --status 会显示默认发行版、默认版本(1 还是 2)、以及内核是否正常;wsl --version 则显示 WSL 程序自身的版本号。
这两个命令容易混淆,记住:--status 是看系统的状态,--version 是看程序的版本。排查问题的时候两个都跑一遍,心里就有底了。
启停控制是管理命令里最实用的一批。单个发行版卡死或者想释放某个发行版占用的内存,用:
powershell复制wsl --terminate Ubuntu-22.04
整个 WSL 虚拟机需要整体重启时,用:
powershell复制wsl --shutdown
--shutdown 是一个非常重要的命令。修改 .wslconfig 之后,必须执行 wsl --shutdown 再重新打开 WSL,配置才会生效。很多人改了配置发现没效果,就是因为没有重启虚拟机。
Windows 11 23H2 及以上版本还有一个 wsl --system 命令,用来进入 WSL 的 System 发行版。这是一个特殊的内置发行版,运行着 WSL 在 Windows 侧的附属服务。平时用不到,但如果遇到 WSL 服务异常,可以进入这个发行版查看后台日志。
4.2 备份与迁移:export/import 实战
WSL 把每个发行版打包导出成一个 tar 文件,这个设计我是真的喜欢。换电脑、重装系统、甚至只是想把发行版从 C 盘挪到 D 盘,全靠 export/import 两条命令。
导出:
powershell复制wsl --export Ubuntu-22.04 D:\backup\ubuntu-22.04.tar
导入时有两种方式:一种是把 tar 作为新发行版导入,指定一个新的目录存放数据:
powershell复制wsl --import Ubuntu-22.04-D D:\wsl\Ubuntu-22.04 D:\backup\ubuntu-22.04.tar
这里第二个参数是新的发行版名称,第三个参数是存放目录。导入完成后,原来的发行版和新的可以并存,默认安装的用户名可能丢失,需要重新配置。
还有一种导入方式是直接覆盖现有发行版。先把原发行版注销,再导入,相当于“恢复系统”:
powershell复制wsl --unregister Ubuntu-22.04
wsl --import Ubuntu-22.04 D:\wsl\Ubuntu-22.04 D:\backup\ubuntu-22.04.tar
注意,--unregister 会删掉发行版的全部文件,所有数据都会被清空,而且不会二次确认。我自己的习惯是:运行 unregister 之前,一定要确认最近一次 export 已经完成,而且要检查导出的 tar 文件大小是正常的(一般 1GB 以上的发行版导出的 tar 也有数百 MB),避免备份文件损坏。
4.3 磁盘空间回收与删除清理
WSL 的虚拟磁盘(VHD)文件有一个特点:只增不减。你在 WSL 里删除了大文件,Windows 侧 C 盘的空间并不会自动释放,因为虚拟磁盘文件本身不会自动缩小。
这个问题用命令解决。首先执行:
powershell复制wsl --shutdown
然后以管理员身份打开 PowerShell,执行:
powershell复制diskpart
在 diskpart 里依次执行:
code复制select vdisk file="C:\Users\<用户名>\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu22.04LTS_<随机字符串>\LocalState\ext4.vhdx"
attach vdisk readonly
compact vdisk
detach vdisk
执行完就能看到磁盘空间被释放。这里注意 VHD 文件的具体位置因为发行版不同而不同,Ubuntu 在 CanonicalGroupLimited 开头,Debian 在 Debian 开头的目录里。这个操作本质上就是压缩虚拟磁盘,不会影响 WSL 里的数据,但建议还是先备份再操作。
5. 配置与调优:让 WSL 用起来更顺手
5.1 两个配置文件的分工
WSL 有两个配置文件,容易搞混。Windows 侧的是 .wslconfig,放在用户目录下:
powershell复制C:\Users\<用户名>\.wslconfig
这个文件管理的是整个 WSL 虚拟机的全局配置,包括内存、CPU、交换分区、网络模式等。修改后执行 wsl --shutdown 再重启生效。
Linux 侧的是 wsl.conf,放在每个发行版内部的 /etc/wsl.conf。这个文件管理的是单个发行版的行为,比如是否自动挂载 Windows 驱动器、默认用户等。修改后执行 wsl --terminate <发行版> 再重启生效。
简单来说:.wslconfig 是“虚拟机”级别的配置,wsl.conf 是“发行版”级别的配置。
5.2 内存、CPU 与交换空间调优
WSL 2 默认会占用本机一半的内存,如果机器只有 16GB,WSL 就可能占用 8GB,这在跑大型编译、容器服务时很快会吃满。通过 .wslconfig 可以限制资源占用。
这是我常用的配置:
ini复制[wsl2]
memory=4GB
processors=4
swap=2GB
swapFile=D:\\wsl\\swap.vhdx
localhostForwarding=true
几个关键参数说明:
memory:限制 WSL 最大内存。写 4GB 表示最多用 4GB,不够用再加。processors:限制 WSL 使用的 CPU 核心数。不设的话默认使用所有核心,某些场景下会导致 Windows 侧卡顿。swap:交换空间大小。内存吃紧时,系统会把不常用的内存页交换到 swap 文件。swapFile:swap 文件的位置。默认在 C 盘,建议挪到大容量分区。localhostForwarding:是否让 WSL 里监听的端口能够通过 localhost 从 Windows 访问。默认是 true,一般不用改。
配置完成后,执行 wsl --shutdown,再重新运行 WSL,配置立即生效。
有人问:为什么我设置了 memory=4GB,但 WSL 还是占用了更多内存?这是因为 WSL 2 的机制是内存按需使用,配置的值是“上限”,而不是“预分配”。只有 WSL 内部进程真正用到那么多内存时,Windows 任务管理器里才会看到占用升高。
5.3 网络模式与镜像网络
WSL 2 默认的网络模式是 NAT,WSL 内部是一个独立的网络命名空间,通过 Windows 宿主做地址转换。在大多数场景下没问题,但如果你在 WSL 里跑服务,需要用 Windows 访问,或者反过来,偶尔会遇到端口不通、IP 变化的问题。
新版 WSL 支持镜像网络模式(mirrored mode),在 .wslconfig 里加一行:
ini复制networkingMode=mirrored
镜像模式下,WSL 和 Windows 共享网络接口,IP 地址一致,端口也直接共享。好处是网络行为更接近原生 Linux,尤其在跑 Docker、Kubernetes 这些需要复杂网络配置的场景下,省了很多麻烦。
这个模式在 Windows 11 22H2 及以上版本可用。如果你的 Windows 版本较老,不支持镜像模式,可以用端口转发命令来手动转发,但操作起来繁琐,遇到再单独处理吧。
5.4 GPU 直通与 CUDA 配置
WSL 2 另外一个重量级特性是支持 GPU 直通。在 WSL 里跑 PyTorch、TensorFlow,或者做 CUDA 开发,不用再单独装一个 Linux 双系统。
前置条件只有两个:Windows 侧安装好 NVIDIA 显卡驱动,驱动版本要支持 WSL;然后进入 WSL,执行:
bash复制nvidia-smi
能看到显卡信息就说明直通已经生效。接下来安装 CUDA Toolkit 时,要选择 WSL-Ubuntu 对应版本,官方提供专门的 WSL 安装包。安装完成后,写一个简单的 PyTorch 脚本来验证 GPU 可用:
python复制import torch
print(torch.cuda.is_available())
print(torch.cuda.get_device_name(0))
如果输出 True 和显卡型号,就说明环境已经就绪。WSL 里跑 CUDA 和原生 Linux 基本没有差异,这对深度学习的开发体验来说是巨大的提升。
不过要提醒一句:WSL 里的 /usr/local/cuda 路径有时候会和系统自带的版本冲突,安装 CUDA 前最好检查一下当前的 PATH 环境变量,避免编译时链接到旧版本。
6. Windows 与 Linux 互操作与自动化
6.1 双向调用:把 WSL 当工具包用
WSL 最让我觉得顺手的一点,就是可以在 Windows 和 Linux 之间双向调用程序。
在 Windows 侧调用 Linux 命令,格式是:
powershell复制wsl -d Ubuntu-22.04 -- bash -c "ls -la /home"
也可以用 -e 指定命令:
powershell复制wsl -d Ubuntu-22.04 -e grep "error" /var/log/syslog
反过来,在 WSL 里调用 Windows 程序也非常自然。比如在 Linux 环境下打开 Windows 的记事本:
bash复制notepad.exe ~/test.txt
也可以用 Windows 的浏览器打开当前目录下某个 HTML 文件:
bash复制explorer.exe .
这个功能的原理是 Windows 会把 Windows 可执行文件所在的路径自动加入到 WSL 的 PATH 里。如果遇到 command not found 的报错,多半是 PATH 配置被修改了,检查一下 /etc/wsl.conf 里的 appendWindowsPath 设置,保持默认的 true 就行。
6.2 文件互通:/mnt/c 与 \wsl$
WSL 里可以直接访问 Windows 的磁盘:
bash复制ls /mnt/c/Users/
反过来,Windows 侧访问 WSL 里的文件,在资源管理器地址栏输入:
code复制\\wsl$\Ubuntu-22.04\home\用户名\
这里有一个性能问题值得注意:如果跨系统读写大量文件,速度会明显慢于同一系统内的读写。比如在 WSL 里编译一个大型项目,如果工作区在 /mnt/c 下,编译速度会比在 /home 下慢不少,因为 /mnt/c 的 IO 经过了一层 9P 协议转换。我的习惯是:代码文件放在 WSL 的 /home 目录下,Windows 侧需要访问时用 \\wsl$ 路径过去,这样两边兼顾。
如果需要在 Windows 和 Linux 路径之间转换,可以用 wslpath 工具:
bash复制wslpath 'C:\Users\test\file.txt'
# 输出:/mnt/c/Users/test/file.txt
6.3 用 WSL 跑 Linux 工具链:以 binwalk 为例
很多人装 WSL 只是为了用某个 Linux 工具,最典型的就是固件分析领域的 binwalk。
binwalk 是一个固件分析工具,用来扫描固件文件里嵌入的文件系统、压缩包、镜像等结构。在没有 WSL 之前,在 Windows 上做固件分析要么装虚拟机,要么装 Cygwin,都很麻烦。有了 WSL,直接:
bash复制sudo apt update
sudo apt install -y binwalk
扫描固件结构:
bash复制binwalk firmware.bin
提取嵌入的文件系统:
bash复制binwalk -e firmware.bin
-e 会自动尝试递归提取识别到的文件。binwalk 在 WSL 里运行,和原生 Linux 环境基本没差别,这就体现了 WSL 作为“Linux 工具链运行环境”的价值。不只是 binwalk,还有 strings、hexdump、file、objdump 这一大票 Linux 生态里的逆向工程、漏洞分析、系统管理工具,在 WSL 里都能顺手用上。
6.4 用批处理脚本把 WSL 管理自动化
管理命令用来用去,最后一定会走上“脚本化”这条路。我这里分享几个自己用的批处理脚本。
一键进入开发环境的脚本 dev.bat:
batch复制@echo off
wsl -d Ubuntu-22.04 -- bash -c "cd ~/work && exec bash"
一键终止所有 WSL 发行版的脚本 wsl-stop.bat:
batch复制@echo off
wsl --shutdown
echo WSL has been stopped.
一键备份所有发行版的脚本 wsl-backup.bat:
batch复制@echo off
for /f "tokens=1 delims= " %%d in ('wsl -l -q') do (
wsl --export %%d D:\backup\%%d-%date:~0,4%%date:~5,2%%date:~8,2%.tar
)
echo Backup completed.
注意 wsl -l -q 会以纯名称格式列出发行版,方便脚本处理。
这套脚本可以和 Windows 计划任务结合。比如每天晚上 2 点执行备份,或者每次开机时自动启动某个开发环境。WSL 管理命令全部支持非交互式执行,写成脚本后非常稳定。
7. 高频问题与修复实录
7.1 “wsl -d ubuntu-22.04 系统找不到指定的文件”排查
这是网上出现频率最高的 WSL 报错之一。在 PowerShell 里执行命令,系统提示“系统找不到指定的文件”,排查步骤如下。
第一步,先看发行版是否真的注册了:
powershell复制wsl -l -v
如果列表里没有 Ubuntu-22.04,说明发行版没装成功或者被注销了,重新安装即可。
如果列表里有这个发行版,但还是报错,大概率是发行版注册信息与真实文件不匹配。这种情况常常出现在从旧版 WSL 升级到新版,或者系统做过迁移之后。处理办法是先注销再重新导入:
powershell复制wsl --unregister Ubuntu-22.04
wsl --import Ubuntu-22.04 D:\wsl\Ubuntu-22.04 E:\backup\ubuntu-22.04.tar
如果你没有备份,那这个发行版里的数据可能就丢了。所以我说 export 是好习惯。
第二步,检查默认发行版配置。有时候 -d 指定的发行版已经在列表里,但系统默认发行版指向了一个失效条目,这也会导致“找不到指定的文件”。执行:
powershell复制wsl --set-default Ubuntu-22.04
第三步,更新 WSL 内核和程序:
powershell复制wsl --update --web-download
很多怪问题都是 WSL 程序版本和 Windows 系统版本不兼容导致的,更新一下就能解决。
7.2 WSL 内存占用过高、启动慢、关机失败
任务管理器里总是看到 Vmmem 进程吃掉大量内存,这个进程就是 WSL 2 的虚拟机进程。解决思路在上面 5.2 已经提过,配置 .wslconfig 限制内存即可。
如果设置了内存限制后发现不生效,确认两点:配置项名称拼写是否正确(注意是 memory 不是 mem);修改后是否执行了 wsl --shutdown 并重新打开 WSL。
启动慢的问题,常见原因是 Windows Defender 实时扫描 WSL 的虚拟磁盘文件。解决方案是把 VHD 文件路径加入 Windows Defender 的排除列表,或者把整个 C:\Users\<用户名>\AppData\Local\Packages 目录下的 WSL 相关文件夹加入排除项。这个操作能明显提升启动速度。
WSL 关机失败时,可以强制结束:
powershell复制wsl --shutdown
taskkill /f /im wslservice.exe
然后重新启动 WSL。注意 taskkill 需要管理员权限。
7.3 网络与 DNS 异常
经典场景:WSL 里执行 sudo apt update 超时,或者 ping 能通但 curl 不通。这类问题在 WSL 2 的 NAT 网络模式下比较常见。
首先排查 DNS 配置。在 WSL 里查看 /etc/resolv.conf:
bash复制cat /etc/resolv.conf
如果 nameserver 指向一个奇怪的地址,说明 DNS 配置被自动生成了但不对。最简单的解决方式是开启 WSL 的镜像网络模式:
ini复制networkingMode=mirrored
dnsTunneling=true
dnsTunneling 会把 DNS 解析请求直接转发给 Windows 宿主,能解决大部分 DNS 异常问题。
如果不想改配置文件,也可以临时手动指定 DNS 服务器:
bash复制sudo sh -c 'echo "nameserver 223.5.5.5" > /etc/resolv.conf'
但 WSL 重启后这个文件可能被覆盖,治标不治本。
7.4 用事件查看器定位 WSL 故障
最后分享一个很多人不知道的排查技巧:Windows 事件查看器。
WSL 的运行日志会写入 Windows 事件日志,来源名称一般是 LxssManager 或 WSLService。打开事件查看器:
powershell复制eventvwr.msc
点击“创建自定义视图”,在“事件来源”里选择 LxssManager 和 WSLService,时间范围选最近一小时,就能看到 WSL 的启动、崩溃、异常记录。
这个操作在 WSL 启动异常、但又没有任何错误提示时尤其有用。比如发行版注册表损坏、虚拟磁盘挂载失败、服务启动超时,都会在这里留下记录。
配合 WSL 内部的 Linux 侧日志,比如 dmesg、journalctl,基本能把问题定位到具体层级:是 Windows 侧的问题,还是 WSL 内核的问题,还是发行版内部的问题。
最后再说一个我自己的经验:WSL 本质上是可重建的,所以管理它的心态应该和管一台随时可以重装的服务器一样。定期 export、合理配置内存、保持 WSL 程序更新,这套管理命令用熟之后,Windows 上跑 Linux 不会再有任何手足无措的时刻。
