What is WSL?

Windows Subsystem for Linux (WSL) allows users to run a Linux terminal environment, install packages from the Ubuntu archive, and run Linux applications and workflows on Windows 10.

What is WSL 1?

The original WSL is now known as WSL1. WSL1 is a compatibility layer for running Linux binary executables (ELF) natively on Windows 10. No re-compilation or 'porting' of applications is required. WSL1 provides a Linux-compatible kernel interface developed by Microsoft that allows a user to choose a Linux distribution to install from the Microsoft Store. WSL1 executes unmodified Linux ELF64 binaries by operating a Linux kernel interface on top of the Windows kernel in Windows 10. The WSL1 interface translates Linux system calls from the binaries into Windows system calls and then executes them at native speed. Linux applications run within the Linux distribution which provides the application's dependencies and package management in a container-like environment. WSL provides an interface to mount drives within WSL.

What is WSL 2?

WSL2 was announced at Microsoft Build 2019. WSL2 features a Linux kernel running inside Windows 10 and is built on the core technology of Hyper-V to provide better Linux application support and improved file performance. Transitioning to WSL2 is seamless. To update to WSL 2 you need Windows 10 version 1903 or higher, with Build 18362 or higher.

Enabling WSL in Windows 10

Before you can install Ubuntu on WSL, WSL has to be enabled in one of the following ways:

Using the GUI for enabling Windows features

  1. Open the Start Menu and search Turn Windows features on or off

  2. Select Windows Subsystem for Linux

  3. Click OK

  4. Restart your computer when prompted

Using PowerShell

  1. Open PowerShell as Administrator and run:

       1  Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
  2. Restart your computer when prompted

Additional Installation Resources

Ubuntu on WSL

Installing Ubuntu on WSL via the Microsoft Store (Recommended)

The recommended way to install Ubuntu on WSL is through the Microsoft Store.

The following Ubuntu releases are available as apps on the Microsoft Store:

  • Ubuntu 16.04 LTS (Xenial) is the first release available for WSL. It supports the x64 architecture only. (offline installer: x64)

  • Ubuntu 18.04 LTS (Bionic) is the second LTS release and the first one supporting ARM64 systems, too. (offline installers: x64, ARM64)

  • Ubuntu 20.04 LTS (Focal) is the current LTS release, supporting both x64 and ARM64 architecture.

  • Ubuntu (without the release version) always follows the recommended release, switching over to the next one when it gets the first point release. Right now it installs Ubuntu 20.04 LTS.

Each app creates a separate root file system in which Ubuntu shells are opened but app updates don’t change the root file system afterwards. Installing a different app in parallel creates a different root file system allowing you to have both Ubuntu LTS releases installed and running in case you need it for keeping compatibility with other external systems. You can also upgrade your Ubuntu 16.04 to 18.04 by running ‘do-release-upgrade’ and have three different systems running in parallel, separating production and sandboxes for experiments.

Installing Ubuntu on WSL via rootfs

Ubuntu WSL distribution rootfs daily builds are available for download:

They can be installed using the wsl command:

  •    1  wsl --import <DistributionName> <InstallLocation> <FileName>

Installing Ubuntu on WSL by sideloading the .appx

Ubuntu WSL distribution .appx builds are available for download:

They can be installed by enabling sideloading in Windows 10 and double-clicking the .appx and clicking Install or with PowerShell:

   1 Add-AppxPackage .\CanonicalGroupLimited.Ubuntu18.04onWindows_1804.2018.817.0_x64__79rhkp1fndgsc.Appx

Running Ubuntu on WSL

Starting Ubuntu on WSL

The Ubuntu on WSL terminal can be started via:

Installing Packages on Ubuntu

Package management on Ubuntu on WSL works the same as on desktop Ubuntu, using the apt package manager. apt will download and install packages from the Ubuntu archive.

First we check for updates:

   1 sudo apt update

We use sudo because installing packages is an administrator task and requires elevated privileges. Enter the UNIX password you created when you installed Ubuntu on WSL. This will not be your Windows password.

Next we can install a package:

   1 sudo apt install hello

For more information on managing packages with apt, see the following additional resources:

Keeping Ubuntu Updated in WSL

WSL runs its own specialized init system instead of SystemD and does not run standard Ubuntu services. Due to the services not running software updates are not applied automatically. Please keep your WSL installation using APT maintenance commands regularly. This can be accomplished with an occasional:

   1 sudo apt update
   2 sudo apt upgrade -y

Hello World

Lets write and compile a very simple Linux application on WSL. It will announce 'Hello World!' and then count to 10.

First, we will update apt and then install the necessary tools, often called dependencies:

   1 sudo apt update
   2 sudo apt install nim

Next, we will create and open a file named helloworld.nim:

   1 nano helloworld.nim

Copy and paste the following code snippet (click 'Toggle Line Numbers' to hide line numbers). You can paste into the Ubuntu on WSL terminal by right-clicking with the mouse or Shift+Ctrl+'V':

   1 echo "Hello World!"
   2 for i in countup(1, 10):
   3   echo i

Exit nano with Control+'X' then press 'Y' and Enter.

Next we will compile our application back at our shell prompt:

   1 nim compile helloworld.nim

This compiles our Nim code snippet to C and then into a Linux binary named helloworld.

Then we can run our Linux binary:

   1 ./helloworld

You should see:

   1 Hello World
   2 1
   3 2
   4 3
   5 4
   6 5
   7 6
   8 7
   9 8
  10 9
  11 10

But we are not just on Linux, we are on WSL.

We can build and test on both Linux and Windows at the same time, including compiling our Hello World application for Windows.

To do this we need to add a dependency, mingw-w64:

   1 sudo apt install mingw-w64

Let's compile our application again, this time creating a Windows binary:

   1 nim compile --gcc.exe:x86_64-w64-mingw32-gcc --gcc.linkerexe:x86_64-w64-mingw32-gcc --cpu:amd64 --os:windows --out:helloworld.exe helloworld.nim

Then move our binary to Windows and run it from within WSL (your path by vary based on your Windows username):

   1 mv helloworld.exe /mnt/c/Users/Hayden/OneDrive/Desktop/
   2 cmd.exe /c "C:\Users\Hayden\OneDrive\Desktop\helloworld.exe"

Learn more about Nim.

Advanced Topics


Ubuntu's performance in WSL1 can be close to bare metal Ubuntu installations in mostly CPU-intensive tasks but file operations are much slower in WSL (see tests on Windows 10 April 2018 Update and on Windows builds from 2019). In WSL 2, CPU intensive tasks are measured to be slightly slower and file operations are generally faster than on WSL1.

Intra-WSL filesystem I/O will always be faster than WSL<->Windows filesystem I/O. It is recommended to move large files and git repos over to WSL to work with them on WSL. To improve performance of the file operations some sites suggest disabling anti-virus software. This puts your system at risk and we highly recommend against doing so.

Running Graphical Applications

The X Window System Architecture allows running the X server and the X clients on separate systems and in WSL's case the X server can be a native Windows server providing even OpenGL acceleration and the clients can be the graphical Linux applications running in the WSL environment.

Install one from several X servers available for Windows and start it before entering the WSL environment:

If graphical applications can't connect to the running X server automatically paste the following commands to the terminal before starting the applications or set them on every login by adding them to ~/.bashrc:

  •    1  export DISPLAY=:0 # in WSL 1
       2  export DISPLAY=$(awk '/nameserver / {print $2; exit}' /etc/resolv.conf 2>/dev/null):0 # in WSL 2
       3  export LIBGL_ALWAYS_INDIRECT=1

Alternatively one can start the XServer (e.g., vcxsrv.exe using a saved config.xlaunch) and start a XWindows session from a Windows DOS batch file. Using this method, one can use DOS ipconfig to determine the virtual ethernet WSL2 IP and set the DISPLAY environment variable before starting the session. This is useful because the virtual ethernet IP will CHANGE with each Windows reboot (thus the need for the use of awk in the export DISPLAY above). Name the batch file whatever seems best for the purpose (note comments in this batch file code) and execute from same directory where the config.xlaunch file is (in this script c:\bin\):

  •    1 @echo off
       3 rem Works ONLY if Ethernet adapter vEthernet (WSL): is the LAST "adapter" in
       4 rem the ipconfig output; that is, this for loop assigns the IPs from first to
       5 rem last from the ipconfig printed output, so the WSL virtual adapter must be the 
       6 rem last one in the ipconfig output for this to work correctly.
       7 rem If you have excellent DOS batch file skills, you may find a better
       8 rem way of doing this.
      10 for /f "tokens=1-2 delims=:" %%a in ('ipconfig^|find "IPv4"') do set ip==%%b
      11 set ipAddress=%ip:~1%
      13 rem Trim whitespace
      15 call :TRIM %ipAddress% ipAddress
      17 rem Use this for testing
      19 rem echo IP Address: %ipAddress%
      21 rem Start up the xServer using saved xlaunch configuration
      22 rem This configuration creates a single large window
      24 start /B config_one_window.xlaunch
      26 rem Start up PulseAudio server, will accept audio from external
      27 rem source, i.e., from the X server 
      29 start "" /B "C:\bin\pulseaudio-5.0-rev18\pulse\pulseaudio.exe"
      31 rem Call ubuntu.exe, have it run what is essentially a startup 
      32 rem script that sets two ENV variables using the ipAddress variable
      33 rem created above, which is the virtual IP to which services
      34 rem INSIDE the running X server can connect; these are the
      35 rem link between WSL2 and Windows 10
      36 rem Initiate an xfce4 session with dbus-launch
      37 rem when the X server is killed, do cleanup by 
      38 rem killing pulseadio and vcxsrv
      40 <PATH_TO_UBUNTU_EXE>\ubuntu.exe run "export DISPLAY="%ipAddress%:0.0"; export PULSE_SERVER="%ipAddress%"; if [ -z \"$(pidof xfce4-session)\" ]; then  dbus-launch --exit-with-session ~/.xsession; pkill '(gpg|ssh)-agent'; taskkill.exe /IM pulseaudio.exe /F; taskkill.exe /IM vcxsrv.exe; fi;"
      42 rem Function to trim white space or the export VARIABLE will fail
      44 :TRIM
      45 SET %2=%1
      46 GOTO :EOF

Enabling Sound

The WSL environment does not support audio, but it can be enabled by installing the PulseAudio server on Windows following this guide. With the latest wslu package installed the starting Ubuntu app detects the running PulseAudio server and enables audio.

Getting Help

Common Issues

  • 'WSL 2 requires an update to its kernel component.' Solution

  • Error codes, e.g. 'Error: 0x80070002' Solution

Reporting Windows Subsystem for Linux-specific Issues

Please report general WSL issues on GitHub.

Reporting Issues in Ubuntu

Please use the standard Ubuntu channels described in ReportingBugs.

Reporting Issues in the Ubuntu WSL Apps

Please report issues related to WSL-specific features in Ubuntu on WSL here.

Additional Resources

WSL (last edited 2021-02-10 04:59:11 by jstalnak)