Windows Subsystem for Linux (WSL)
文档用途
这篇文档用于介绍 Windows Subsystem for Linux, 简称 WSL.
官方文档 Windows Subsystem for Linux Documentation | Microsoft Learn.
使用场景
- 相比于
云服务器, 可以将 WSL 作为测试服务器, 很多测试工作不再需要使用云服务器. - 相比于
虚拟机, WSL 系统启动速度快 (1秒), 比很多 Windows 软件启动速度都快. - 相比于
双系统, 能同时运行两个系统以及其中的软件, 没有系统切换的困扰. - WSL 的文件系统可以和 Windows 的文件系统
互操作, 也就是共享硬盘中的数据. - Windows 系统内置命令行工具
wls, 用于管理 WLS, 简单易用.
安装与卸载
BIOS 虚拟化
需要确保 BIOS 中开启了虚拟化.
如何为 BIOS 开启虚拟化 (ChatGPT)
要为计算机的 BIOS 启用虚拟化技术,你需要按照以下步骤进行操作:
打开计算机并进入 BIOS:
- 通常,在开机时会出现一个提示,告诉你按下某个键(比如Del、F2、F10等)可以进入 BIOS 设置。这个提示通常会在屏幕的左下角或右下角显示。
- 如果你不确定应该按哪个键,可以在启动时尝试按下多个可能的键,直到进入 BIOS 为止。
导航至虚拟化设置:
- 一旦你进入 BIOS,使用键盘上的方向键和回车键来导航和选择选项。具体的界面和选项可能会因制造商和 BIOS 版本而异,但通常你会找到一个类似于 "Advanced", "Advanced Settings", "CPU Configuration" 或者 "Security" 的选项。
启用虚拟化技术:
- 在高级设置中,你需要寻找与虚拟化技术相关的选项。这通常称为 "Virtualization Technology", "Intel Virtualization Technology", 或 "AMD-V"(取决于你的 CPU 品牌)。
- 将其设置为 "Enabled" 或类似的选项。
保存并退出:
- 一旦你启用了虚拟化技术,找到一个选项来保存设置并退出 BIOS。通常,你会在退出时被提示是否保存更改。
重新启动计算机:
- 让计算机重新启动以使更改生效。
请注意,这些步骤可能会因计算机品牌、型号和 BIOS 版本而异,因此在进行更改之前,请务必查看计算机的用户手册或在互联网上查找特定于你的计算机的指导。同时,在进行 BIOS 更改时要小心,不要更改你不了解的其他设置,以免导致系统不稳定或无法启动。
系统功能
需要启用以下两个 Windows Feature.

默认安装
# 确保内核版本是最新
wsl --update --inbox
# 只需这一行命令即可完成安装, 并自动启动
wsl --install
输入命令后, 大概需要等几分钟, 就能看到上图中的文字以及安装进度.
安装完成后, 需要重启电脑, 然后会自动完成后续安装流程.
此时需要设置默认的用户名和密码, 之后系统会自动启动, 以命令行的形式.
选择发行版
# 列出所有 wsl 所支持的发行版
wsl --list --online
# 安装指定的发行版
wsl --install -d [发行版名称]INFO
执行 wsl 的一些指令时, 可能会遇到下图中的错误.
这是因为 DNS 被污染了, 通过域名无法找到正确的 IP. 解决方案: 使用网络代理.

卸载
WARNING
以下操作会永久删除 WSL 发行版中的数据, 对需要保留的数据请务必做好备份.
wsl --list # 查看已安装的 WSL 发行版
wsl --unregister [distribution-name] # 删除指定发行版先执行以上命令, 再通过 Windows 默认的软件卸载方案移除.

基本使用
开始会话
可以直接通过 Windows 的搜索功能找到 Ubuntu, 运行即可.
如下图所示, 按下 Win 键之后, 直接搜索, 就像运行一个普通软件一样.

如果安装了 Windows Terminal, 那么可以打开一个新的标签页.
在安装 WSL 时, Ubuntu 这个标签页会被自动添加到 Windows Terminal 中.

以上两种方式, 都会使用安装 WSL 时所创建的用户 (有管理员权限, 可使用 sudo).
如果想直接以 root 用户登录, 则应该执行以下命令:
wsl -u root # 在宿主系统的命令行中执行, 例如 powershell文件互传
类似于云服务器的文件传输, 可以使用 scp 等命令.
但没必要, 因为有更简单的文件传输手段: 直接在文件浏览器中复制粘贴.
在 WSL 中运行以下命令, 可以通过 Windows 的文件浏览器打开 Linux 的当前路径.
然后就直接通过文件浏览器, 把文件复制粘贴到目标路径即可.
explorer.exe .有些时候可能无法将文件复制到某些路径, 这是因为存在权限问题.
解决方案: 将文件复制到有写入权限的路径, 再通过 sudo mv 命令移动至目标路径.
或者直接在 文件浏览器 里输入 \\wsl.localhost\[发行版名称] (将定位到系统根目录).
互操作
如果想在 Windows 的命令行中使用 WSL 的命令, 可以这么做:
wsl ls -a # 此命令在 Windows 中执行, 调用了 WSL 的 ls -a 命令如果想在 WSL 中执行 Windows 的命令, 可以这么做:
explorer.exe . # 此命令在 WSL 中执行, 调用了 Windows 的 explorer . 命令TIP
甚至可以在一行语句中混合执行 WSL 和 Windows 的命令.
VS Code
vscode 的远程开发特性配合 WSL 非常完美.
vscode 本身就支持使用 ssh 远程开发, 其中 vscode 编辑器作为前端运行在本地设备上,
通过 ssh 协议与远程服务器连接, 语法高亮, 智能提示等功能运行在服务器上.
微软官方提供了 vscode 插件, 使得我们可以更方便地讲 WSL 作为开发环境.
插件配置: 安装 Remote Development 插件包 (其中包含远程开发以及 WSL 相关插件).

在 WSL 中执行此命令, 就会在 Windows 中运行 vscode, 并以当前路径作为工程根目录:
code . # 在 WSL 中执行有些插件运行在服务端, 需要在 WSL 安装.
需要在 WSL 中安装的插件如下图所示, 点击按钮即可安装.

配置代理
TIP
最简单的方案是使用 Tun Mode, 此方案无需下面这些额外的操作.
原理简述
很多情况下我们都需要使用代理来访问被墙的资源, 或是加快下载速度 (例如 github).
如果宿主系统 (也就是 Windows) 开启了, 此时还需要额外做一些事情才能给 WSL 使用.
WSL 有一个虚拟网卡, 和宿主系统的网卡不是同一个.
因此需要间接通过宿主系统的网卡上网, 具体来说, 网络流量需要经过代理端口.
参考 为 WSL2 一键设置代理 和 WSL2配置代理 - Leaos (cnblogs.com).
宿主系统
首先需要确保宿主系统的代理软件开启了 "允许局域网 (Allow LAN)".
如下图所示, 以 clash 举例, 需要开启红圈中的选项.
另外可以注意到, vpn 端口号为 7890, 这个端口会在后面的配置中用到.

还需要确保 clash 相关进程的防火墙设置是正确的.
通过查看 Windows Defender Firewall, 如果发现 clash 相关进程的图标是红色,
则应该 (在 clash 未启动的情况下) 选中并删除这些防火墙设置, 然后重新运行 clash.

首次运行 clash 时, 会触发以下两个弹窗, 注意勾选 Private networks.


WSL 环境变量
通过 WSL 中的 /etc/resolv.conf 文件得知宿主系统的 IP 地址:
# 此命令在 WSL 中执行
cat /etc/resolv.conf如下图所示, 红圈中内容是宿主系统的 IP 地址.

使用命令配置代理, 设置临时的环境变量, 会话结束后会失效:
# 此命令在 WSL 中执行
export all_proxy="<宿主系统 IP>:<vpn 端口号>"
# 如果按照上面两张截图, 命令就应该写成
export all_proxy="172.19.96.1:7890"通过访问谷歌, 检验是否成功设置.
如果收到了 html 格式的消息, 则说明成功设置网络代理.
curl google.com # 此命令在 WSL 中执行
简化操作
如果每次需要重复上述操作, 多少有些麻烦, 因此在这里介绍一些用于简化操作的手段.
将下面这个文件放在 WSL 的任意位置 (下文假设文件位置是 /opt/proxy.sh).
展开查看 proxy.sh 脚本内容
#!/usr/bin/sh
# Setup proxy in CLI
BASEDIR=$(dirname "$0")
CUSTOM_FILE=$BASEDIR/custom.sh
PORT=7890
WSL_SUPPORT=false
if [ $WSL_SUPPORT = false ]; then
HOST_IP="localhost"
elif [ $WSL_SUPPORT = true ]; then
HOST_IP=$(cat /etc/resolv.conf | grep nameserver | awk '{ print $2 }')
else
echo "\$WSL_SUPPORT should be either 0 or 1"
exit 1
fi
if [ -z $HOST_IP ]; then
exit 1
fi
PROXY_HTTP="http://${HOST_IP}:${PORT}"
set_proxy() {
export all_proxy="${PROXY_HTTP}"
export ALL_PROXY="${PROXY_HTTP}"
git config --global http.https://github.com.proxy "${PROXY_HTTP}"
git config --global https.https://github.com.proxy "${PROXY_HTTP}"
echo "Proxy has been opened."
echo "Port:" $PORT
check_status
}
unset_proxy() {
unset all_proxy
unset ALL_PROXY
git config --global --unset http.https://github.com.proxy
git config --global --unset https.https://github.com.proxy
echo "Proxy has been closed."
}
check_status() {
echo "Try to connect to Google..."
RESP=$(curl -I -s --connect-timeout 5 -m 5 -w "%{http_code}" -o /dev/null www.google.com)
if [ ${RESP} = 200 ]; then
echo "Proxy setup succeeded!"
else
echo "Proxy setup failed!"
fi
}
help_msg() {
echo
echo "proxy.sh can be used to setup proxy in CLI"
echo
echo "Suported arguments:"
echo " set setup proxy and check status"
echo " unset unset proxy"
echo " status check whether proxy is setup"
echo " help print help message"
echo
}
if [ "$1" = "set" ]; then
set_proxy
elif [ "$1" = "unset" ]; then
unset_proxy
elif [ "$1" = "status" ]; then
check_status
elif [ "$1" = "help" ]; then
help_msg
elif [ "$1" = "--help" ]; then
help_msg
elif [ "$1" = "" ]; then
help_msg
else
echo "Unsupported arguments."
fibash 的配置文件是 ~/.profile, zsh 的配置文件是 ~/.zprofile.
在 shell 的配置文件中新增一行:
alias proxy="source /opt/proxy.sh"文件修改完成后, 记得使用 source ~/.profile 命令使得配置立即生效.
至此配置已经完成, 之后只需要调用以下命令, 就能方便地开启或关闭代理:
proxy set # 启用代理
proxy unset # 禁用代理
proxy status # 测试代理是否起效笔记
VIM 剪切板
我们希望能够让 WSL 中的 vim 和 Windows 系统共享剪切板.
这项功能需要名为 clipboard 的 vim feature 支持.
我们可以通过以下命令查看当前已安装的 vim 是否支持:
# 此命令在 WSL 中执行
vim --version | grep clipboard如果看到 +clipboard 则说明支持, 如果看到的是 -clipboard, 则说明不支持.
如果 vim 不支持 clipboard, 就需要安装其他版本的 vim:
# 此命令在 WSL 中执行
sudo apt install vim-gtk3 -y最后请确保 ~/.vimrc 中有这条语句:
set clipboard^=unnamed,unnamedplusNeovim
剪切板使用 win32yank.
详见笔者的 Neovim 配置文件 GitHub 仓库.
Systemd
默认情况下, WSL 并未启用 systemd.
如果执行 systemctl 命令会遇到以下错误:
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down解决方案是, 修改 (或新建) /etc/wsl.conf 文件, 在其中添加以下内容:
(如果希望将此设置作用于所有 WSL 实例, 那么应该修改 ~/.wslconfig 文件)
[boot]
systemd=true然后在宿主系统 (Windows) 中执行以下命令:
wsl --shutdown之后进入 WSL 时, systemd 就启用了.