Saturday, June 20, 2020

Windows10 运行Ubuntu - WSL2

参见2019年2月的blog:Running Linux on Windows。WSL2是微软第二代Windows Subsystem for Linux。WSL2与WSL的区别可以参考Comparing WSL 2 and WSL 1。简单说,WSL1提供了Linux shell支持,但底层是把Linux移植到Windows内核上,所以不支持系统调用(system call),不支持Linux Kernel,有诸多限制,不易扩展,不易移植。WSL2则是把Linux内核运行在虚拟机上,支持完整的system call,Linux程序可以直接拿过来编译运行,缺点主要是需要打开虚拟机支持(Hyper-V),与现行的VMWare和Virtual Box有冲突(好消息是VMWare和Virtual Box的新版本都将支持Hyper-V);另一个问题是固有的Linux对Windows文件系统的支持问题(虽然Linux支持NTFS和FAT,可由于Windows文件系统没有Linux文件权限支持(如root, group, owner),也不支持Linux symbolic link,在cross OS的文件系统方面有一定限制。
Comparing WSL 2 and WSL 1提到只有如下两种情况可以考虑使用WSL1而不是WSL2:
  • Your project files must be stored in the Windows file system.
    • If you will be using your WSL Linux distribution to access project files on the Windows file system, and these files cannot be stored on the Linux file system, you will achieve faster performance across the OS files systems by using WSL 1.
  • A project which requires cross-compilation using both Windows and Linux tools on the same files.
    • File performance across the Windows and Linux operating systems is faster in WSL 1 than WSL 2, so if you are using Windows applications to access Linux files, you will currently achieve faster performance with WSL 1.
In fact, there is other cases you may want to use WSL1, such as WSL2 ticket #4322 for accessing Windows USB device from WSL: Ubuntu 18.04 Serial devices are no longer mounted properly. It’s clearly called out in the FAQ that there is currently no support for USB in WSL2. It is a highly desired feature, but unfortunately still not available after almost two years as of today. Good news is: you can switch back to WSL1, and it is very easy to do the 'downgrade', no installation, no reboot needed, just run one command from Power Shell:
wsl --set-version Ubuntu 1
The same Linux Distribution installed for WSL2 should still work as is. 
WSL support很早就在Windows Insider build里提供了,并且正式出现在updated to version 2004, Build 19041 or higher。参见微软link安装指南。微软的安装指南里没有提到直接安装WSL2,而是谈到如何从WSL1升级到WSL2, 实际上用户不需要安装WSL1, 然后再升级到WSL2。安装WSL2可以直接从安装Linux Kernel package 开始。然后去微软AppStore选个Linux安装。WSL2本身只提供在Windows上运行Linux的支持,真正的Linux系统需要另外安装,用户可以选择Ubuntu, Debian, Alpine等。不同发行的Linux都基于相同的Linux内核(可能是不同内核版本),可能不同的内核配置,不同的软件包,图形界面等。详情参见Wikipedia
安装完Linux,运行wsl用户会发现只有terminal终端界面。如果想要图形GUI界面,则需要借助x server的支持,详情参见Ubuntu Wiki。 
Update@Jul 28, 2022:
If you are on be on Windows 11 Build 22000 or later, you can take the latest feature from WSL which supports Linux GUI APPs. Please refer to https://docs.microsoft.com/en-us/windows/wsl/tutorials/gui-apps. If you are still on older Windows 10 like me, you may refer to this WSL issue 4106 on github for some reference information. For me, Cygwin-X server is not working for WSL2, though it works for my Cygwin GUI APPs, probably due to lacking the capability to disable access control.VcXsrv Windows X Server download | SourceForge.net works for me, with access control disabled. Also works with MobaXterm (free Home Edition) built-in X server in similar way.And one more note on this is: for setting the DISPLAY environment variable on WSL2 side, I have to use the my wireless IP which is actively connected, and my Ethernet cable wasn't connected. Cannot use the command from above Ubuntu Wiki link as:
export DISPLAY=$(awk '/nameserver / {print $2; exit}' /etc/resolv.conf 2>/dev/null):0 # in WSL 2
The output of above command is IP for Ethernet adapter vEthernet (WSL). For some reason it just doesn't work, not sure is it due to company's network setting, or some other reason. If have VPN connected, may need to use the VPN IP. So if it is not working, try all the IP you can get from ipconfig's output, except the vEthernet of WSL. Loop back IP 127.0.0.1 won't work either.
 
If seeing error like "cannot execute binary file: Exec format error", refer to this Stackoverflow post: https://stackoverflow.com/questions/42120938/exec-format-error-32-bit-executable-windows-subsystem-for-linux. Likely user installed 64bit Linux and was trying an 32bit executable. Need to enable 32 bit support with command:
sudo dpkg --add-architecture i386
sudo apt-get update
If seeing the error with GCC, might also need to do:
sudo apt install gcc:i386
and maybe below as well:
sudo apt-get install gcc-multilib g++-multilib libc6:i386
And likely this only works with WSL2. If you updated from WSL1, running
 wsl --set-default-version <Version#>
won't affect distribution already installed on your PC. You can run: "wsl -l -v" to check distribution name and which WSL version it is. To change WSL version, run:
wsl --set-version <distribution_name> 2
and it will take a little time to convert.
Refer to bash - What is the home directory on Windows Subsystem for Linux? - Super User for how to access the guest distro folder from host Windows OS (\\wsl$\Ubuntu). From guest distro such as Ubuntu to host Windows C: drive, it is mounted as: /mnt/c  
 
Update on Nov 24: per several website such as xda-developers.com, the latest WSL also enabled Windows 10 user to run GUI application. It also brings in systemd support.