刚接触 WSL 的人,十个里有八个会跟我当年一样:在 Windows 命令行里敲了个wsl --install,看到一堆输出飘过去,然后一脸懵——这到底装到哪去了?怎么进 Linux?怎么访问我 D 盘里的文件?为什么wsl命令和Linux命令总有一种割裂感?这篇文章就是要把 WSL 的命令体系彻底讲透,从安装、路径转换、开发环境搭建,到发行版迁移、网络排查、常见报错,全部用“命令 + 实操经验”的方式捋一遍。适合两类人:一是 Windows 下做开发、想有一套顺手 Linux 环境的朋友,二是已经装了 WSL 但遇到各种奇怪问题、不知道怎么排查的老用户。我尽量按实际使用频率来排布内容,你会看到哪些命令值得背下来,哪些只需收藏备用。
1. 安装与初始化:从零开始把 WSL 装到顺手
1.1 安装命令与 WSL 1 / WSL 2 的选择逻辑
先说最基础的。Win10 较新版本和 Win11 都支持一条命令直接装:
wsl --install这条命令做完的事其实不少:启用 Windows 的“适用于 Linux 的 Windows 子系统”可选功能、启用虚拟机平台、下载并安装默认发行版(通常是 Ubuntu),然后提示你重启。装完重启后,首次进入需要创建 Linux 用户名和密码。
还有一个很多人会碰到的变体:
wsl --install --web-download--web-download的意思是从网络直接下载发行版,而不是用 Windows 商店的安装通道。某些离线环境或商店组件有问题时,这条命令能救急,但它对网络质量要求更高,我曾经在没加这个参数卡住后,加上它反而顺利装完了,后来才明白是商店通道本身出问题了。如果你发现wsl --install长时间卡住不动,多半就是下载源的问题,后面第 5 章我再细说排查思路。
装完之后,强烈建议先确认两件事:
wsl --version # 查看 WSL 程序自身版本(WSL 2.0+ 会显示详细版本号) wsl -l -v # 列出已安装发行版及当前 WSL 版本wsl -l -v输出里会看到你安装的发行版名字,以及VERSION列是 1 还是 2。WSL 2 基于真正的轻量虚拟机,文件系统性能和 Docker 兼容性都大幅领先,除非硬件太老不支持虚拟化,否则一律用 2。
注意:不要在不知道
-l -v含义时乱加参数。wsl -l -v等价于wsl --list --verbose,而wsl -l -o是查看在线可装发行版列表。这几个简写经常有人记混。
查看在线发行版列表用:
wsl --list --online这里会列出 Ubuntu、Debian、Kali、openSUSE 等。安装指定发行版就是:
wsl --install -d Debian我在一台老笔记本上装过 Debian 13(当时还在测试期),步骤跟 Ubuntu 几乎一样:wsl --install -d Debian,然后进系统改软件源、装开发工具,没有遇到额外阻碍。Debian 的资源占用比 Ubuntu 更小,如果你只是需要基础 Linux 环境,可以试试它。
1.2 把系统装到 D 盘:迁移发行版与默认路径设置
wsl --install默认把虚拟磁盘放到 C 盘用户目录下,路径类似:
C:\Users\你的用户名\AppData\Local\Packages\...\LocalState\ext4.vhdx这个文件就是整个 Linux 系统的“硬盘”,几十 GB 很正常。C 盘紧张的人迟早会遇到“WSL 挤爆系统盘”的问题。官方支持的迁移方式是导入导出,不是直接剪贴文件:
# 1. 先关闭所有 WSL 分发版 wsl --shutdown # 2. 导出当前发行版为 tar 文件 wsl --export Ubuntu D:\wsl_backup\ubuntu.tar # 3. 注销原发行版(会删除原系统,但 tar 已保存) wsl --unregister Ubuntu # 4. 导入到新位置 wsl --import Ubuntu D:\WSL\Ubuntu D:\wsl_backup\ubuntu.tar --version 2打包解包的过程可能持续十几分钟,tar 文件体积等同于已用空间。等导入完成后,再执行wsl就能进入系统了。这里有个坑:用--import导入的发行版,默认登录用户是 root,而不是你原来的账户。补救方法是进出 WSL 后执行:
# 在 WSL 里进入系统后 sudo nano /etc/wsl.conf在文件中写入:
[user] default=你的用户名然后wsl --shutdown再重进,用户名就对了。这个配置文件还能设置挂载参数、系统初始化命令等,后面章节会用到。
如果你没有迁移需求,只是想让以后新装的发行版都放 D 盘,那没有全局设置项,只能按“导出-注销-导入”这条路走。所以最省事的做法其实是:第一次安装前就预估好空间,C 盘紧张就直接用wsl --import方案,或者干脆先清理 C 盘。网上流行的“改环境变量”办法,实测并不对所有 Windows 版本生效,别浪费时间。
2. 日常高频命令:文件、路径与磁盘操作必知必会
2.1 路径互转:wslpath 与 /mnt 挂载机制
Windows 和 Linux 的路径体系完全不同。在 WSL 里,Windows 的各个盘符会被挂载到/mnt目录下:
C:\ → /mnt/c/ D:\ → /mnt/d/也就是说,你在 WSL 里想读取 D 盘某个文件夹,直接cd /mnt/d/项目文件夹就行。反过来,在 Windows 的 cmd 或 PowerShell 里要看 Linux 内部路径,可以这样进:
wsl cd ~ wsl pwd不过更常用的是把 WSL 里当前目录直接映射到 Windows 文件资源管理器:
explorer.exe .这个命令会在 Windows 资源管理器里打开当前 Linux 目录,注意它实际访问的是\\wsl$\Ubuntu\home\用户名\...这个网络路径。喜欢用文件管理器拖拽文件的人,这条命令可以帮大忙。
真正的“路径转换神器”是wslpath:
wslpath "C:\Users\abc\test.txt" # 输出 /mnt/c/Users/abc/test.txt wslpath -w /home/abc/test.txt # 输出 C:\Users\abc\AppData\Local\... 这类 UNC 路径-w表示转成 Windows 路径,-m表示以/分隔的 Windows 路径。写脚本时,如果你需要把 WSL 里的文件路径传给 Windows 程序,先wslpath -w一下,避免手滑填错。
2.2 在 WSL 中访问 Windows 磁盘与文件权限那些事
访问/mnt/c和/mnt/d时,很多新手会发现 Linux 文件权限显示成drwxrwxrwx,甚至chmod 777都不生效。这是 WSL 的 DrvFs 文件系统挂载特性导致的——它默认把 Windows 文件系统的权限映射成了“所有人可读写”,因为 Windows 本身没有 Linux 那套权限模型。
想调整挂载行为,在/etc/wsl.conf里加:
[automount] enabled = true options = "metadata,umask=22,fmask=11"加了metadata之后,WSL 会把 Linux 权限记录在 Windows 文件系统的扩展属性里,chmod和chown就能在 /mnt 下使用了。我做 Node 项目时经常因为node_modules权限问题崩溃,加了这个配置之后少了很多怪毛病。
还有一个非常实用的场景:Windows 下解压 tar.gz 包经常不顺手,其实可以直接在 WSL 里操作 Windows 文件:
# 在 WSL 中,先切到 /mnt/d 下的目录 cd /mnt/d/downloads tar -xzf 某压缩包.tar.gz因为 WSL 的 tar 命令处理符号链接、权限比 Windows 自带解压工具靠谱得多。热词里有人问“Windows 怎么用命令解压 tar”,答案其实就是“进 WSL 用 tar”,没有比这更高效的方式了。
注意:给
/mnt/c里的项目跑npm install或pip install,跨文件系统的 IO 会比较慢,而且偶发文件锁问题。正式开发项目尽量放在 Linux 原生路径~/下,别放在 /mnt 下跑大任务。
2.3 从 Windows 命令行调用 WSL 单条命令
除了进入交互式 Shell,wsl命令可以直接执行单条 Linux 命令,这个技巧在写自动化脚本时非常实用:
wsl ls -la /home wsl sudo apt update wsl python3 /home/user/test.py甚至可以把 Windows 环境变量传进去:
wsl -e sh -c "echo $env:USERNAME"在写 Windows 批处理时,需要 grep 或 awk 处理文本,我也会直接调 WSL:
wsl grep "error" C:\logs\app.log注意这里传入的是 Windows 路径,WSL 会自动转换,但转换逻辑偶尔不如wslpath可控,复杂路径建议先手动转好。
3. 开发环境搭建:VS Code、Docker、CUDA 与 PyTorch 实战
3.1 在 VS Code 中使用 WSL:不只是“打开远程”
VS Code 官方对 WSL 的支持已经到了“无感”的程度。装好 [WSL] 扩展后,在 WSL 终端里敲:
code .它会自动启动 VS Code,并连接到你当前的 WSL 发行版。左下角会显示一个类似 “WSL: Ubuntu” 的标记,代表整个编辑器、终端、调试器都跑在 Linux 环境里。Windows 桌面上的文件拖不进 WSL 项目目录?直接右键文件夹“在 WSL 中打开”也行。
在 VS Code 里配好远程开发环境后,最爽的是 Python 环境隔离:你在 WSL Ubuntu 里创建 venv 或 conda 环境,VS Code 会自动检测到解释器,Ctrl+Shift+P里选 “Python: Select Interpreter” 就能看到。默认的终端也直接是 Linux Bash,不用再开独立的 WSL 窗口。这个工作流我现在每天都用,Windows 写前端、WSL 跑后端服务,同一编辑器里无缝切换。
一个小技巧:如果你在 Windows 侧装了 VS Code,又在 WSL 里装了 code CLI,注意两个code命令有冲突。默认情况下,拿到 WSL 里那个code才是对应远端入口。如果你发现code .打开的是 Windows 版本,试着在 Windows 里执行wsl -e code .,或者在 WSL 里重装一次 VS Code Server 组件。
3.2 用 Docker 的完整姿势:Docker Desktop 与 WSL 2 联动
热词里有 “docker 更新后运行不了 wsl”、“windows docker desktop wsl”。这类问题非常典型。先说正确架构:Docker Desktop 在 Windows 上不再用 Hyper-V 虚拟机,而是直接基于 WSL 2 作为后端,也就是 Docker Desktop 设置里的 “Use WSL 2 based engine” 选项。
联动成功时,WSL 内的docker命令直接指向 Docker Desktop 的引擎,可以做到:
docker ps docker compose up -d跟原生 Linux 体验一致。问题往往出现在 Docker Desktop 更新之后,它会重建自己的 WSL 发行版(通常是docker-desktop和docker-desktop-data),如果旧发行版被锁住或损坏,就会出现 WSL 报错、Docker 起不来。排查命令:
wsl -l -v # 看 docker-desktop 发行版状态 wsl --shutdown # 冷重启所有发行版然后再启动 Docker Desktop,一般能恢复。如果还不行,去 Docker Desktop 设置里找到 “Troubleshoot”,点 “Clean / Purge data” 可以重置后端,但会清掉镜像和容器,刷之前先docker save导出需要保留的镜像。
WSL 内直接安装 Docker Engine 也能用(不装 Docker Desktop),但容器端口映射、与 Windows 宿主机的共享网络,配置起来比 Docker Desktop 麻烦不少。我的实测经验是:日常开发优先 Docker Desktop 联动,生产部署再按 Linux 原生方式学 Docker 命令不迟。
涉及 containerd 时,docker run命令其实是在调用 containerd 来创建容器。如果你偶尔看到Failed to connect to containerd报错,十有八九是 Docker 后端没起来,按上面说的先wsl --shutdown再启动 Docker Desktop。
3.3 WSL 2 里装 CUDA 与 PyTorch:一次配好就吃灰的稳定方案
WSL 2 支持 NVIDIA GPU 直通,这是深度学习能在 Windows 下流畅跑起来的核心。不过,很多人第一次装就被坑了——在 WSL 里装 CUDA,其实你不需要在 WSL 里安装完整的 NVIDIA 驱动驱动。正确流程分两步:
第一步,Windows 侧安装 NVIDIA 驱动。注意要选支持 WSL 的版本,GeForce Game Ready 或 Studio 驱动都带 WSL 支持。只要 Windows 侧驱动装好了,nvidia-smi在 WSL 里可以直接运行,看到的就是 GPU 信息。
第二步,在 WSL Ubuntu 里安装 CUDA Toolkit。官方推荐用runfile或 apt 源安装。apt 方式大致是:
wget https://developer.download.nvidia.com/compute/cuda/repos/wsl-ubuntu/x86_64/cuda-keyring_1.0-1_all.deb sudo dpkg -i cuda-keyring_1.0-1_all.deb sudo apt update sudo apt install cuda装完以后,重启终端,nvcc --version能看到版本就说明 CUDA 编译器就位了。接下来建 PyTorch 环境:
# 创建虚拟环境 python3 -m venv ~/pytorch_env source ~/pytorch_env/bin/activate # 安装 PyTorch(以 CUDA 12.1 为例) pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121验证是否真的能调 GPU:
python -c "import torch; print(torch.cuda.is_available()); print(torch.cuda.get_device_name(0))"输出True和显卡型号,就是成功了。这里有几个专属于 WSL 的注意点:
- WSL 里的 CUDA 版本优先级是“Windows 驱动支持的 CUDA 版本”,不一定要装最新版。你 Windows 驱动是最新的,那 CUDA 基本都能跑,但 PyTorch 编译版本要匹配。
nvidia-smi显示的是驱动版本和 CUDA 驱动版本,不代表你已经装了 CUDA Toolkit。nvcc才是 Toolkit 的标志,两者很容易混淆。- 如果你在 WSL 里报
CUDA error: no kernel image is available,多半是 PyTorch 的 CUDA 版本和驱动不匹配,换一个 cu 版本的安装命令试试。
这套环境我配一次之后基本就不用再动,Windows 驱动更新也不会影响 WSL 里的 CUDA,除非你的 PyTorch 需要更高版本。
4. Linux 基础命令速查:git、vim、shell 里高频用到的那点事
4.1 Git 命令高频操作流
WSL 里最常用的工具大概就是git。装好后的第一件事是设置身份:
git config --global user.name "你的名字" git config --global user.email "你的邮箱"日常提交流程我基本固定为:
git status # 先看修改 git diff # 再确认改动内容 git add . # 加入暂存区(new files / modified) git commit -m "描述" git push # 推送远程分支操作里,我用得最多的是:
git switch -c 新分支 git merge 目标分支注意git switch比旧版的git checkout -b更直观,新项目建议统一用switch,少一层含义。很多人卡在“撤销”上,记住三个场景:
git restore 文件 # 撤销工作区修改 git restore --staged 文件 # 把已暂存的内容退回工作区 git reset --hard HEAD # 丢弃所有未提交修改(慎用)最后一条是“悔不当初”级命令,会在没有提示的情况下删掉你的工作区修改,我现在都会再三确认git status干净才会用。
4.2 Vim 命令:新人突破“不会退出”的怪圈
WSL 里默认编辑器多半是 nano 或 vim。热词里单独出现“vim命令”,说明新手受困很深。Vim 的核心就一句话:普通模式、插入模式、命令模式三态切换。
- 打开文件:
vim 文件名 - 进入插入模式:按
i,此时可以正常打字 - 退回普通模式:按
Esc - 保存退出:普通模式下输入
:wq回车 - 不保存退出:普通模式下输入
:q!回车
文件内查找替换:
:/password # 向下搜索 password :%s/old/new/g # 全局替换 old 为 new行号显示和格式化:
:set number gg=G # 自动缩进整个文件真实使用时,我建议新手直接把Esc键映射成jj或者Ctrl+[,因为一直按 Esc 手很酸。在 WSL 里,vim 配置放到~/.vimrc,我自己的基础配置就三行:
set number set tabstop=4 set expandtab这样做的好处是,无论你之后开发什么语言,缩进都不会乱。Vim 入门不需要背命令大全,先能编辑、保存、退出、搜索,剩下的等你真觉得卡手再查。
4.3 Shell 命令里容易被忽略的进阶细节
热词里出现了一串 shell 相关词条:history、shift、数组切片、并行执行命令。这些恰好是写脚本的高频需求,我逐个说。
history命令看执行记录:
history # 全部历史 history | grep "docker" # 搜索历史里的 docker 命令 !123 # 重新执行历史第 123 条 !! # 重新执行上一条命令shift用于脚本参数左移。写一个批量处理脚本时:
#!/bin/bash while [ $# -gt 0 ]; do echo "处理参数: $1" shift done每次shift,$2变$1,$#减一。适合处理-n 10 -f file这类参数串。
数组切片是 Bash 的一个冷门但高效功能:
arr=(a b c d e) echo "${arr[@]:1:3}" # 从第 2 个元素开始取 3 个:b c d并行执行 Linux 命令,最简单的写法:
command1 & command2 & wait&把命令放到后台,wait等所有后台任务结束。批量压缩多个文件夹时,这个技巧能节省大量等待时间。
热词里还提到“linux删除文件夹命令”,基础到不行但也经常有人问:
rm -rf 目录名 # 强制递归删除 rm -i 目录名 # 逐个提示确认(更安全)我记得有一年在生产服务器上一个手滑rm -rf /,至今心有余悸。WSL 里也一样,rm -rf慎用,尤其是在/mnt/c下操作,一旦删错,回收站可帮不了你。
5. WSL 高级管理命令与问题排查实录
5.1 发行版的导入导出、启动停止与彻底卸载
前面说过导出导入是迁移系统的核心方案。这里我再补几个重要的生命周期命令:
wsl --shutdown # 关闭所有发行版(相当于把虚拟机断电) wsl --terminate Ubuntu # 关闭特定发行版 wsl -d Ubuntu # 直接进入指定发行版 wsl --unregister Ubuntu # 彻底注销发行版(删除数据!)wsl --terminate在发行版卡死时非常有用。有一次我跑了个内存爆炸的 Python 脚本,整个 WSL 假死,Windows 里其他程序都正常。我一开始找任务管理器重新开 Mintty 窗口,没用,后来才想起命令行敲:
wsl --terminate Ubuntu几秒后重新进入就恢复了。这比重启电脑或关闭 Docker Desktop 高效得多。
Windows 开机自启 WSL 里的服务,可以在任务计划程序里设置,或直接把命令放在.bashrc。我在.bashrc里加了启动 Docker 或数据库服务的判断逻辑,但更推荐用systemd。新版 WSL 2 已经默认支持 systemd,启用方式是在/etc/wsl.conf里写:
[boot] systemd=true然后wsl --shutdown再启动,systemctl status就能看到 Service 管理起来了。我目前用 systemd 管理 SSH 服务和定时任务,比裸写crontab与nohup规范不少。
5.2 网络与 DNS 问题排查:能不能上网、为什么慢
WSL 网络问题最常见的就是“apt update 很慢”和“git clone 卡住”。先说结论:多数慢的问题不是 WSL 的问题,而是默认软件源在国外。解决 apt 慢的标准做法是更换软件源镜像:
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak sudo sed -i 's|http://archive.ubuntu.com/ubuntu|http://mirrors.aliyun.com/ubuntu|g' /etc/apt/sources.list sudo apt update不同发行版源格式略有差异,Debian 还需要再版配置。改完源之后,再apt update基本秒级。
pip 下载慢同样可以通过镜像解决:
pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple还有一类网络问题是 WSL 里无法访问局域网,或者 Windows 防火墙拦截。检查顺序:
ping 网关 # 看基础连通性 ip addr # 看 WSL 网卡地址 curl -v https://example.com # 看出口是否通如果从 Windows 侧访问 WSL 里的服务连不上,先确认你监听的地址是0.0.0.0而不是127.0.0.1。WSL 2 是 NAT 网络,Windows 访问 WSL 服务通常需要手动端口转发,配置起来略麻烦。常见做法是:
netsh interface portproxy add v4tov4 listenport=8080 listenaddress=0.0.0.0 connectport=8080 connectaddress=127.0.0.1WSL 每次重启 IP 可能变化,通过localhost访问是最省心的方式。WSL 2 在较新版本中默认支持 localhost 回环,所以大多数开发场景不用管端口转发这回事。
5.3 高频报错与解决:安装慢、命令找不到、弹窗闪退
最后整理一份我实测过的常见问题表,按出现频率排:
| 现象 | 常见原因 | 解决方法 |
|---|---|---|
wsl --install卡住或失败 | 商店组件异常 / 下载源缓慢 | 用wsl --install --web-download重试;检查网络后重启再试 |
| 启动 WSL 报“启动分发失败” | 虚拟化未开启 / 发行版文件损坏 | BIOS 开启虚拟化;wsl --shutdown后重开,必要时重新导入 |
WSL 内command not found | 软件包确实没装 | sudo apt install 对应包名,比如sudo apt install rpm |
wsl命令显示“不是内部或外部命令” | 系统版本过旧或未启用 WSL 功能 | 确认 Windows 版本号,启用“适用于 Linux 的 Windows 子系统”可选功能 |
| Docker Desktop 启动后 WSL 崩 | Docker 后端发行版损坏 | wsl --shutdown,再启动 Docker Desktop;无效则重置 Docker 数据 |
WSL 内nvidia-smi不存在 | 驱动问题 | 在 Windows 侧更新 NVIDIA 驱动;确认 WSL 里能看到/dev/nvidia*设备 |
“找不到 rpm 命令”这个问题,我在 Debian/Ubuntu 系里碰到很多次,原因是 rpm 文件格式和安装包管理工具属于 RedHat 系,Ubuntu 系里默认不装。如果你需要装.rpm包,要么加装rpm工具(转成.deb用alien),要么直接用.deb包。我也不知道为什么总有人想用 Ubuntu 装 rpm,大概是被某个只提供 rpm 包的工具坑的吧。
热词里“windows弹窗提示命令”和“脚本闪退”也常被问到。脚本闪退多半是因为批处理执行到一半遇到语法错误或者崩溃,排查思路是在 cmd / PowerShell 里加暂停:
cmd /k 你的脚本.cmd或者用pause让窗口不立刻关闭,先看报了错再处理。我是建议写脚本时尽量用 PowerShell 或 Bash 而非纯 cmd,至少报错信息能看懂点。
“麒麟V10命令重启后为什么网卡不启动”这类问题(如果你用的是国产 Linux 发行版在 WSL 里或物理机里),本质是网络服务未启用或 NetworkManager 配置异常,可以依次检查:
systemctl status NetworkManager ip a sudo systemctl restart NetworkManager如果在 WSL 里遇到这个,多半是虚拟网卡启动顺序问题,把[network]相关配置写进/etc/wsl.conf或找个稳定的服务自启手段就好。不过说实话,在 WSL 内部不建议过度折腾网卡配置,底层网络归 Windows 管。
还有一类偏门的排查需求,比如用 binwalk 做固件分析:
sudo apt install binwalk binwalk 固件.bin在 WSL 里跑 binwalk 是可行的,如果你的固件分析需要处理大量二进制内容,记得先检查是否有足够内存,并且把工具链版本装到 Python3 环境里。
一些安全测试工具比如 sqlmap、arpspoof,也有人问怎么在 WSL 里用。核心提示是:这些工具只应在你拥有授权的设备和网络环境里测试,比如自己搭的靶机或 CTF 平台。安装方式同样是apt install,但分发版里的版本往往不够新,需要从源码拉 GitHub 仓库编译,这正好用得上前面说的 git 命令。给新手一点建议:先用 Docker 容器跑这类工具,能少踩很多依赖坑,容器删了又不留垃圾。
最后单独说说“telnet 命令怎么用”。老牌网络排查工具 telnet 由于默认不安装,在 WSL 里先sudo apt install telnet,然后:
telnet 192.168.1.1 23更多时候是拿它测端口通不通,比如:
telnet example.com 443能进入黑屏光标状态就说明 TCP 端口可达。我一般用nc -vz example.com 443代替 telnet,因为脚本友好度更高,而且 WSL 里自带 netcat 的概率大一些。
结合这些年在 WSL 里进进出出的经验,我的总体建议是:不要试图在 WSL 里复刻一台完整的生产 Linux 服务器,它就是你在 Windows 桌面下的“开发环境副驾驶”。安装命令、路径转换、开发环境三大块是高频刚需,建议练熟;发行版迁移、systemd、网络排查属于“会用一次就值回时间”的中频技能,收藏这篇够了。如果你以后换电脑,别忘了用wsl --export和wsl --import把整套环境搬走,那才是 WSL 最香的长线收益。