过去几年,我在Windows上做Linux开发,踩过无数坑,最后固定下来的方案就是WSL。WSL这个缩写,全称Windows Subsystem for Linux,这几年几乎是Windows开发者绕不开的词。我最早接触它是为了在Windows上直接跑Linux命令行,不用再开虚拟机,也不用重启切双系统。用下来的感受很直接:它不是一个玩具,而是一个能真正承载日常开发、Docker、CUDA、甚至小型服务器的子系统。这篇文章适合刚准备入坑WSL、或者装了WSL但用得很难受的人,我会从安装、路径、环境搭建、日常踩坑到迁移备份,把整个流程里值得注意的细节一次讲透。
1. 为什么我在Windows上最终选了WSL而不是虚拟机或双系统
1.1 从一次编译失败说起,WSL到底解决了什么问题
很多人的入坑经历都类似:Windows上写代码写得好好的,突然有一天要编一个Linux下的C/C++库,或者部署一个只提供Linux安装脚本的服务,然后噩梦就开始了。我记忆最深的一次,是在Windows下编译一个基于epoll的网络库,明明代码没问题,一编译就报一堆系统调用相关的头文件缺失。那时候我用过MinGW,也试过Cygwin,但很多库对它们的支持并不完整,最后只能临时借一台Linux服务器去编。
WSL解决的就是这个“想要Linux环境又不想放弃Windows桌面”的尴尬。它不是一个模拟器,也不是一个普通虚拟机,而是微软在Windows内核里放了一个真正兼容Linux的系统调用接口。在WSL2里,微软直接使用了一个轻量级虚拟机跑完整的Linux内核,所以你可以在里面跑systemd、跑Docker容器、跑CUDA程序,绝大多数Linux软件都能直接用。对于开发者来说,最核心的价值是:日常办公、聊天、开浏览器用Windows,写代码、跑服务、做运维操作用WSL,两边文件互相可见,剪贴板互通,端口也能互相访问。
默认情况下,Windows的文件系统路径会挂载在WSL里的/mnt/c、/mnt/d,Linux侧的文件也能在Windows资源管理器里输入\\wsl$直接访问。这个互通机制让我省去了大量文件拷贝的时间。以前在虚拟机里改了代码,还要想办法同步出来;现在直接在Windows的VS Code里改,终端用WSL跑,保存即生效,体验非常顺。
1.2 WSL1和WSL2到底有什么区别,为什么我最终用WSL2
如果你搜WSL的资料,一定会看到WSL1和WSL2这两个版本。简单说,WSL1是把Linux系统调用翻译成Windows系统调用的兼容层,它启动快、跟Windows文件系统交互快,但有些偏底层的Linux程序跑不了,比如Docker、需要完整内核模块的程序,在WSL1里基本没戏。WSL2则是一个真正的迷你虚拟机,里面跑的是一个完整Linux内核,兼容性大幅提升,绝大多数Linux二进制文件都能直接运行。
代价是WSL2的IO性能比WSL1弱一些。尤其是直接读写/mnt/c下的Windows文件时,跨文件系统会有比较大的性能损耗。我自己实测过在WSL2里编译一个中等规模的Go项目,如果把源码放在Linux侧~/project,比放在/mnt/c/project能快将近一倍。所以我的习惯是:代码、依赖、数据库文件都放在WSL的Linux文件系统里,只有需要跟Windows软件交换的文件才放到/mnt路径下。
WSL2还有一个让我最终放弃WSL1的点:它支持systemd。在较新版本的WSL2里,只要在/etc/wsl.conf里开启systemd,就能用systemctl管理服务,装Docker、装数据库都能像在真实服务器上一样操作,不用手动写一堆启动脚本。这一点对于习惯Linux运维的人来说,吸引力是致命的。
2. 安装前必须弄明白的三件事:版本、路径和发行版
2.1 你的Windows版本支持哪种WSL
WSL目前的安装方式比以前简单太多。在Windows 10 2004及以上版本、Windows 11,基本只需要用管理员权限打开PowerShell或Windows Terminal,执行一条命令:
wsl --install这条命令会自动开启需要的Windows功能组件,下载WSL2内核,并默认安装Ubuntu发行版。执行完按提示重启电脑,第一次启动Ubuntu时设置用户名和密码,就完事了。
但如果你还在用老版本Windows 10,或遇到安装失败的情况,需要手动开启两个功能:适用于Linux的Windows子系统和虚拟机平台。在PowerShell里执行这两行,然后重启:
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart启动后,可能还需要手动更新WSL2内核。正常情况下后续通过wsl --update就能保持最新。安装完可以用wsl --status查看当前WSL版本,确认是WSL2。如果你发现自己的发行版跑在WSL1模式下,可以随时用wsl --set-version <发行版名> 2升级到WSL2。
2.2 把WSL系统盘放到D盘的正确姿势
这是新手最容易踩的坑:WSL默认会把发行版虚拟磁盘放到C盘的用户目录下,具体路径类似C:\Users\你的用户名\AppData\Local\Packages\...\LocalState\ext4.vhdx。这个文件会随着你安装软件、写数据不断膨胀,分分钟几十GB。C盘空间紧张的话,用不了多久就红了。
最稳妥的做法是安装完发行版之后立刻迁移到其他盘。核心思路是导出、注销、再导入。具体步骤:
- 先在WSL里把所有服务关掉,回到Windows终端执行
wsl --shutdown。 - 用
wsl --export Ubuntu D:\wsl-backup\ubuntu.tar把当前系统导出成tar包。 - 用
wsl --unregister Ubuntu注销当前发行版,这一步会删除C盘上的虚拟磁盘。 - 用
wsl --import Ubuntu D:\WSL\Ubuntu D:\wsl-backup\ubuntu.tar --version 2把系统导入到D盘指定目录。
导入之后有一个小问题:默认会用root用户登录。解决办法是在导入的Linux系统里编辑/etc/wsl.conf,加上这样一段:
[user] default=你的用户名保存后在Windows终端执行wsl --shutdown,再重新进入WSL,用户就恢复正常了。迁移本身不复杂,但也有不少人导入后忘记设置默认用户,然后发现所有文件权限都变得很别扭,这里提前打个预防针。
如果不想折腾迁移,也可以在安装时就尽量控制体积,比如不装用不到的图形界面、定期清理apt缓存。但该来的还是会来,尽早迁移到D盘是治本的做法。
2.3 请直接装Ubuntu 22.04/24.04 LTS,理由和命令
微软默认安装的发行版通常是Ubuntu,这也是WSL生态里资料最多的发行版。如果你没有特殊偏好,建议直接选Ubuntu LTS版本。理由很现实:Docker、CUDA、PyTorch这些工具在Ubuntu上的官方支持最好,遇到问题一搜就有答案。我个人推荐22.04或24.04 LTS,两者都能在WSL2里稳定运行。
安装指定发行版可以用:
wsl --install -d Ubuntu-22.04或者想用Debian的话:
wsl --install -d DebianDebian 13在WSL2下也能正常跑,而且比Ubuntu更精简,内存占用更低。但对新手来说,Ubuntu的文档和社区资源更丰富,所以我的建议是先用Ubuntu跑通整体流程,熟悉之后想换Debian再切换也不迟。
第一次进入WSL时会要求创建Unix用户名和密码,这个跟Windows登录账号没有关系,是Linux系统内的独立账号。创建之后,建议先跑一遍系统更新:
sudo apt update && sudo apt upgrade -y顺便装上一些基础工具:
sudo apt install -y build-essential git curl wget net-tools到这里WSL的基本环境就算可用了。
3. WSL2的实际开发环境搭建:从Docker到CUDA再到VSCode
3.1 在WSL2里装Docker,为什么不要用Windows里的Docker Desktop
很多人在Windows上第一次接触Docker,装的是Docker Desktop。说实话,Docker Desktop对Windows用户确实友好,但如果你的主力开发环境是WSL2,我更推荐直接在WSL2里安装Docker Engine,而不是依赖Docker Desktop。
原因很简单:Docker Desktop本质上是在Windows侧的虚拟机里跑Docker,再通过WSL集成把命令行转发过来。这层转发有时候会和WSL2自己的网络栈产生奇怪的冲突,比如端口映射偶尔不生效、容器访问Windows服务时IP对不上。直接在WSL2里装原生的Docker Engine,所有容器都运行在WSL2的内核上,网络行为跟真实的Linux服务器几乎一致,排查问题反而更简单。
在WSL2里启用systemd后,安装Docker的步骤比较常规。先执行:
sudo apt update sudo apt install -y docker.io sudo systemctl enable docker sudo systemctl start docker然后把你自己的用户加入docker组,避免每次都用sudo:
sudo usermod -aG docker $USER退出WSL重新进入后,执行docker run hello-world验证。这里要提醒一个细节:WSL环境共享Windows的CPU和内存,但Docker容器默认不自动限制资源。如果你同时跑很多容器,可能把整个WSL2的可用内存耗尽,建议在.wslconfig里提前设置上限。
3.2 Windows下跑CUDA?WSL2的GPU加速和NVIDIA驱动原理
WSL2在GPU加速上做得比很多人想象中好。如果你的Windows机器有NVIDIA显卡,并且Windows侧安装了支持WSL的NVIDIA驱动,那么在WSL2里可以直接调用GPU跑CUDA程序、PyTorch训练、甚至本地跑大模型。这对不想装双系统又想做深度学习的人来说,是个非常实用的方案。
原理上,NVIDIA驱动跑在Windows侧,WSL2的Linux内核通过一套GPU直通机制把CUDA调用传给Windows驱动。所以你需要做的是两件事:第一,确保Windows显卡驱动是最新版;第二,在WSL2里安装Linux版的CUDA Toolkit。驱动本身不用在WSL里重复安装,这跟传统Linux下装显卡驱动完全不一样,别搞混了。
安装CUDA Toolkit官方推荐用NVIDIA的apt仓库,大致流程是:
wget https://developer.download.nvidia.com/compute/cuda/repos/wsl-ubuntu/x86_64/cuda-keyring_1.1-1_all.deb sudo dpkg -i cuda-keyring_1.1-1_all.deb sudo apt update sudo apt install -y cuda装完后用nvidia-smi能看到和Windows侧一致的显卡信息。很多人会在这里纠结要不要装cuda-drivers,在WSL场景下一般不需要,Linux内核模块已经由Windows驱动侧承担。如果你要跑PyTorch,装好CUDA后直接按项目需要安装torch版本即可。我第一次在WSL2里跑通GPU训练时,有种“Windows终于不再是深度学习二等公民”的感慨。
3.3 VSCode连接WSL,远程开发的体验优化
我现在写代码的主力组合是VS Code加WSL。VS Code里装一个“WSL”扩展,然后用code .命令在WSL目录里打开编辑器,整个过程是无缝的。你可以在VS Code的终端里直接跑Linux命令、看Linux文件,扩展也被安装到WSL侧,调试器能直接附加到Linux进程,体验接近SSH远程开发,但免去了网络配置。
需要注意的是,如果你是先开了WSL终端再执行code .,VS Code会自动下载一个server组件到WSL里,这个过程通常很快。如果出现打开不了或连接卡住,先检查Windows和WSL的版本,旧版本WSL的兼容性确实差一些。
对于用PyCharm、GoLand这类JetBrains工具的人,新版工具也原生支持WSL,只需要在项目设置里选择WSL作为解释器或SDK即可。不过体验上还是VS Code最顺,尤其是配合Remote Development全家桶,跨平台开发几乎无感。
4. WSL日常使用中的高频问题和排查记录
4.1 wsl --install太慢或卡住,组件存储损坏怎么处理
wsl --install长时间卡住是最常被吐槽的问题。实际情况可能是后台正在下载组件,终端没有及时刷新显示;也可能确实是Windows组件存储已经损坏。我的排查顺序是:先另开一个管理员终端执行wsl --status看状态,再执行以下两条命令修复Windows组件存储:
dism.exe /Online /Cleanup-Image /RestoreHealth sfc /scannow这两条命令都比较耗时,尤其是DISM,执行完如果发现修复了东西,重启后再重新执行wsl --install。如果还是卡住,可以考虑先把Windows更新补丁打全,再回来装WSL。网上还有用wsl --update --web-download强制在线下载更新的做法,也可以一试。
另外,不要同时用多个终端反复执行wsl --install,这会导致多个下载任务互相争抢文件,更容易出问题。
4.2 WSL内存和CPU占用太高,.wslconfig调优参数
WSL2默认会使用最多50%的物理内存,在16GB内存的机器上就是8GB。如果Windows这边还要跑浏览器、聊天软件,内存立刻吃紧。解决办法是在Windows用户目录下创建.wslconfig文件,内容示例:
[wsl2] memory=6GB processors=4 swap=2GB localhostForwarding=true改完执行wsl --shutdown再重新进入,配置就生效了。注意.wslconfig是全局配置,对发行的所有WSL2发行版生效;如果只想限制某一个发行版,需要在发行版内的/etc/wsl.conf里配,但资源限制这类参数还是.wslconfig更直接。
还有个隐藏问题:WSL2的虚拟磁盘文件(ext4.vhdx)会只增不减,即使你在WSL里删了很多文件,C盘空间也不会自动释放。这时可以在PowerShell里执行wsl --manage Ubuntu --compact,或者用Optimize-VHD命令回收空间。我习惯定期整理磁盘,这招能救回不少硬盘空间。
4.3 WSL里的网络、端口和Windows互访问题
WSL2基于虚拟化网络,它的IP和Windows主机的IP不是一个网段的。默认情况下,Windows可以访问WSL里的服务,比如在WSL里启动一个端口监听,Windows浏览器直接访问localhost:端口即可,因为WSL2开启了localhost转发。反过来,WSL里访问Windows的某个服务,一般用localhost也能通。
如果遇到访问不通的情况,先确认Windows防火墙是否放行了对应端口。毕竟WSL里的流量经过虚拟交换机出来,Windows防火墙有时候会拦截。一个比较实用的命令是:
netsh interface portproxy add v4tov4 listenport=8080 listenaddress=0.0.0.0 connectport=8080 connectaddress=127.0.0.1这可以把WSL里的服务转发到Windows固定端口,方便局域网内其他设备访问。要说明的是,WSL2每次重启IP都可能变化,如果依赖固定IP,最好把服务绑定到localhost,或使用端口转发。
4.4 binwalk等Linux工具在WSL里的使用小技巧
WSL能跑很多Linux下的专业小工具,这让我在Windows上也能做固件分析类工作。binwalk是一个固件分析神器,直接在WSL里安装:
sudo apt install -y binwalk用的时候进入目标目录,执行binwalk 固件文件就能识别文件结构。这里有个小技巧:如果文件在Windows侧,比如在/mnt/c/Downloads目录下,解包速度会慢很多,最好先拷贝到WSL的~/tools目录下再分析。原因就是前面提到的跨文件系统IO性能损耗,binwalk这类需要大量读写的小工具特别明显。
类似的小工具还有很多,比如file、strings、hexdump、tcpdump,在WSL里都是直接apt安装就能用。相当于Windows系统自带了一个完整的Linux工具箱,遇到问题时不必再满世界找Windows版替代品。
5. 卸载、迁移和备份,这些收尾工作其实更重要
5.1 彻底卸载WSL和发行版
如果哪天你想把WSL完全清理掉,不要直接去控制面板删程序,那样经常卸载不干净。正确顺序是先删掉具体发行版,再把WSL功能关闭。
在Windows终端查看当前安装了哪些发行版:
wsl --list --verbose删除某个发行版及其全部数据:
wsl --unregister Ubuntu这一步会直接删掉该发行版的整个虚拟磁盘,数据无法恢复,操作前一定要确认。如果要彻底关闭WSL功能,去“启用或关闭Windows功能”里取消勾选“适用于Linux的Windows子系统”和“虚拟机平台”,重启后即可。
有一点要特别提醒:删了发行版不等删了WSL2内核。只要你以后还想用,推荐保留WSL2内核和虚拟机平台,因为重新安装还是挺费时间的。
5.2 把WSL发行版整个搬到别的电脑
换电脑或者重装系统后,WSL环境重建很花时间。好在我发现可以直接迁移发行版。方法是把旧电脑上的发行版导出成tar包,拷到新电脑再导入。
导出和导入命令跟迁移到D盘的思路一致:
wsl --export Ubuntu D:\ubuntu.tar wsl --import Ubuntu D:\WSL\Ubuntu D:\ubuntu.tar --version 2新电脑需要先安装WSL本身,然后导入。导入后如果发现默认用户是root,再按之前的方法改/etc/wsl.conf即可。如果你的WSL版本够新,wsl --export还支持--vhd参数,可以直接导出整个.vhdx磁盘文件,虽然体积更大,但导入后文件系统结构几乎原样保留,省去一些权限调整的麻烦。
我自己的习惯是把原环境的~/.bashrc、~/.ssh、~/.config先备份一份,即使导入出现问题,也能快速还原关键配置。
5.3 日常备份WSL环境的低成本方案
WSL的日常备份不一定要用大型工具,一个tar包就够。每周抽几分钟执行一次:
wsl --shutdown wsl --export Ubuntu D:\backups\ubuntu-20250101.tar如果担心虚拟机磁盘文件膨胀,更推荐用wsl --export --vhd导出vhd。备份文件放到D盘或移动硬盘后,C盘空间再紧张也不怕。
不过tar包里包含大量个人文件,建议对备份目录做加密压缩,或者至少不要随意放在公共共享目录。WSL环境里的很多密钥、配置文件都跟开发环境强相关,丢了重配真的很头大。
我个人在实际操作中的体会是:WSL最大的价值不是让你在Windows上“模拟”一个Linux,而是让Windows和Linux能好好配合。刚开始装的时候,多用一点时间想清楚分区、版本和迁移方案,后面能省下无数时间。最后再分享一个小技巧:Windows Terminal支持多标签页,可以同时开WSL和PowerShell会话,在WSL里配好tmux之后,一个窗口就能管理多个终端,这在做服务器部署时特别顺手。希望这份踩坑记录能帮你少走几步弯路。