WSL2使用记录
windows平台上,使用wsl2我直呼过瘾!
写在开头:
- wsl2较wsl1有什么改变,见此链接 Comparing WSL 1 and WSL 2
- wsl2的详细文档,见此链接 Dev on Windows with WSL
- 知乎这篇文章写得好面向开发者的 WSL2 安装指南,出于记录目的,我还是在此又bb了一篇
- 官方的安装使用文档在此:Windows Subsystem for Linux Installation Guide for Windows 10
我选择wsl的理由
- 方便快捷
- 易于维护
- 体验优于远程服务器,体验优于vmware、virtualbox
安装配置(针对wsl2)
1. 确认Windows版本
wsl版本 | 系统要求 |
---|---|
WSL1 | win10版本 >= 1607 |
WSL2 | win10版本 == 1903(仅x64)、1909(仅x64)、2004、20H2、最新版本 |
关于win10版本说明:Windows 版本运行状况
国内的总结博客:win10系统版本说明
wiki相关说明:Windows_10版本历史
如何查看本地win10版本
win
+r
=> winver
或者:win
+i
=> 系统 => 关于
2. 启动系统相关功能
win
+s
=> [启用或关闭windows功能]
启用:
- 适用于Linux的Windows子系统
- Hyper-V
或者使用Administrator执行PowerShell命令
- 启用linux子系统:
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
- 启用虚拟机
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
3. 安装Linux内核更新包
msi格式安装程序下载链接,来源于官方:WSL2 Linux kernel update package for x64 machines,下载完成后直接安装。
4. 选中WSL2版本,下载Linux发行版
wsl --set-default-version 2
win10应用商店下载linux发行版:
5.安装完成,启动+设置默认用户
发行版下载完成后,可以作为一个windows应用程序启动,初次启动需要等待一定的时间,启动进入后需要设置默认用户以及登录密码。
6. 选择一个终端登录wsl
已知的登录wsl的方式:
- 直接作为应用软件启动
- cmd 中输入wsl
- powershell中输入wsl
win10官方推荐的一个终端接入工具Windows Terminal.。Ctrl
+Shift
+P
下快捷键一目了然,类似tmux的一些基本功能,窗口分隔之类的。
系统文件迁移
我安装的linux子系统在哪里?我能否转移它?我能否从转移到别的windows系统?
文件资源占用
使用应用商店安装的wsl默认会有个位置:
C:\Users\<User Name>\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu18.04onWindows_79rhkp1fndgsc\LocalState\rootfs\
下面会有一个ext4文件:
之后对于wsl的一切操作,在文件系统层级,都只与这个文件有关系。
导出为tar
关注wsl命令的这个参数:
PS C:\Users\zzxun> wsl -h
--export <分发版> <文件名>
将分发导出到 tar 文件。
对于标准输出,文件名可以是 -。
# wsl -l 可以查看当前系统装有哪些linux分发版
PS C:\Users\zzxun> wsl -l
适用于 Linux 的 Windows 子系统分发版:
Ubuntu-18.04 (默认)
例如导出到E盘下,名称为wsl-ubuntu-18.04.tar
wsl --export Ubuntu-18.04 E:/wsl-ubuntu-18.04.tar
导出过程需要一定时间等待,过程中会占用一定的系统资源:
导出成功后,可以看到生成一个tar文件在对应位置:
注销老的wsl
wsl --unregister Ubuntu-18.04
经过前面几部操作后,原C盘wsl安装目录只占用几KB空间:
从tar导入新的wsl
关注wsl命令的这个参数:
PS C:\Users\zzxun> wsl -h
--import <分发版> <安装位置> <文件名> [选项]
将指定的 tar 文件作为新分发进行导入。
对于标准输入,文件名可以是 -。
选项:
--version <版本>
指定用于新分发的版本。
例如从E:\wsl-ubuntu-18.04.tar导入,安装目录设为E:\WSL\Ubuntu-18.04
wsl --import Ubuntu-18.04 E:\WSL\Ubuntu-18.04 E:\wsl-ubuntu-18.04.tar --version 2
导入成功后可以看到对应目录有生成新的wsl系统文件:
导入成功后,新的wsl可以正常使用了。
开机启动
我想在windows开机时,自动启动wsl里的一些软件,怎么实现?
编写wsl上的sh脚本
wsl下编写/etc/init.wsl脚本。
例如:
#!/bin/sh
/etc/init.d/redis-server start
/etc/init.d/mysql start
/etc/init.d/ssh start
编写windows下的vbs脚本
linux-start.vbs
Set ws = WScript.CreateObject("WScript.Shell")
ws.run "wsl -d Ubuntu-18.04 -u root /etc/init.wsl"
设置windows下的开机执行vbs脚本
win
+R
执行 shell:startup
随后会打开win10下的启动文件夹,将上面编写的vbs脚本放置在此处。
之后启动win10后就会执行此脚本,从而在wsl中运行/etc/init.wsl文件。
基本使用
文件访问互通
win10访问wsl2的文件系统:
explorer.exe \\wsl$\Ubuntu-18.04
就直接在资源管理器下打开了wsl的文件系统。
wsl2访问win10的文件系统:
cd /mnt
win10的磁盘都被挂载在wsl2的/mnt目录下。
网络访问
使用wsl后,本地会多出几个虚拟网卡,如下:Hyper-V相关的虚拟网卡。
在使用win10的wsl2子系统时,windows会通过虚拟交换机给win10本机与wsl2子系统各自会分配一个ip地址,当windows电脑重启并再次打开wsl2时,虚拟交换机会被重新创建,分配给它们的ip地址也会随着改变。
wsl --shutdown
关闭虚拟机之后,再wsl ifconfig
可以看到每次wsl2的ip地址都在变化。
这很不方便,虽然可以通过localhost加端口来访问到wsl2,但是对于需要通过ip来直接访问的一些wsl2中的应用时,总是需要查看一次wsl2所分配到的ip,再进行连接,这很不方便。
哪有没有什么可以给wsl2分配静态ip的方法?
github上关于设置静态ip的issue
其中有一个评论是这么说的:
I give you a new idea: Instead of changing the IP, add a designated IP.
In Windows 10, run CMD or Powershell with administrator privilege, and then execute the following two commands:
:: Add an IP address in Ubuntu, 192.168.50.16, named eth0:1
wsl -d Ubuntu -u root ip addr add 192.168.50.16/24 broadcast 192.168.50.255 dev eth0 label eth0:1
:: Add an IP address in Win10, 192.168.50.88
netsh interface ip add address "vEthernet (WSL)" 192.168.50.88 255.255.255.0
In the future, you will use 192.168.50.16 when you access Ubuntu, and 192.168.50.88 when you access Win10.
You can save the above two lines of commands as a .bat file, and then put it into the boot area, and let it execute automatically every time.
当然也有通过在hosts里动态设置wsl2的ip和对于的访问域名来实现通过域名访问wsl2。
项目地址:go-wsl2-host
最简单的解决方案
直接使用wsl来修改windows的hosts文件,注意,hosts文件没有权限直接修改,需要将其拷贝出来修改完成后再覆盖回去,具体代码如下:
echo "设置hosts"
cp /mnt/c/Windows/System32/drivers/etc/hosts /tmp
sed -i '/wslhost/d' /tmp/hosts
echo "$(hostname -I) wslhost" >> /tmp/hosts
cp /tmp/hosts /mnt/c/Windows/System32/drivers/etc/
echo "设置hosts完成"
需要知道一个命令hostname -I
可以直接获取到wsl子系统的IP地址。
端口转发(搭配内网穿透)
我本地win10连接的openwrt路由器上安装有FRP内网穿透工具,我希望通过内网穿透直接来访问本地的wsl2系统的特定软件端口,此时肯定是不能通过wsl2的IP来直接转发的,需要借助win10在openwrt上分配的ip来做一次转发,将访问到win10特定端口的请求,转发到wsl2的对应端口上。
需要用到win10自带的命令行工具netsh:
- 添加(更新)端口转发
netsh interface portproxy add v4tov4 listenport=[本机端口号] listenaddress=[本机IP] connectport=[目标IP的端口号] connectaddress=[目标IP]
- 删除端口转发(如果添加错了,可以使用这个命令删除已添加的端口映射)
netsh interface portproxy del v4tov4 listenport= [本机端口号] listenaddress= [本机IP]
- 查看已存在的端口映射
netsh interface portproxy show v4tov4
注意端口转发支持对域名进行转发,前面的IP访问设置中,有添加一个wslhost专门用户wsl系统访问,故可以直接为wslhost配置端口转发。
最后,端口转发配置完成,别忘记配置win10的防火墙出入站策略。