/
WSL

WSL

WSL is the “Linux aspect” of Windows. You can execute Linux commands in Windows on your Windows files. You can pipe the output of a Windows command to a Linux program, or pipe Linux output to Windows. In the following example, the Windows winget.exe program generates a list of the current versions (and available update versions) of programs installed in the Windows operating system and the command line pipes this list to the Linux grep command which filters out the lines that contain the word “Git”

C:\Users\gilbert>winget list|wsl grep Git Git Git.Git 2.48.1 winget GitHub Desktop GitHub.GitHubDesktop 3.4.17 winget

WSL creates a very special Linux Virtual Machine running the Microsoft version of the Linux Kernel. Unlike other VMs, the Windows system is tightly connected to this Linux VM. Windows programs can directly access the Linux files, Linux has access to the Windows disks, Linux and Windows programs can share the same network adapters, and you can combine Linux and Windows programs on the same command line.

If you want the full Linux Gnome Desktop experience, create a normal Linux VM with Hyper-V. WSL is command line only, but you can install individual Linux GUI programs into WSL and when you run them an application window pops up on the Windows desktop:

image-20250307-152820.png

The Microsoft Linux Kernel runs a special non-Docker container system. You can install one or more Linux “distributions” (Ubuntu, Debian, SUSE, etc.) each into their own container under the Kernel. Unlike Docker, this special container system lets the distributions run systemd background services and shares resources like network adapters. Each distribution has its own isolated file system, processes, and libraries.

The default and probably best adapted distribution is Ubuntu (24.04 LTS). Ubuntu has supported WSL since the earliest version, installs with systemd and snap enabled, and provides the widest library of programs that you can install and run using the apt package manager.

If you are going to run a sequence of Linux commands, then typing the command “wsl” with no arguments converts the Windows command line into a Linux bash session (like running ssh to a Linux machine on the network). Microsoft also provides a bash.exe command that does the same thing.

There is no way to translate Windows file access control to Linux file permissions. The WSL environment is, therefore, private to each Windows user. If two users are logged into the same Windows machine, each has their own personal copy of WSL Ubuntu. The user has implicit full (root) control over his own WSL system and files. Anything in WSL cannot be directly shared with another user. However, if a WSL service connects to the network as port 8080, then other users on the same machine can connect to localhost:8080 and access the service over what appears to be “the network”.

On Windows, the Linux file system in your Ubuntu distribution is referenced by the Windows UNC name of \\wsl$\ubuntu.

C:\Users\gilbert>dir \\wsl$\Ubuntu\ Directory of \\wsl$\Ubuntu 03/31/2024 04:00 AM <DIR> sbin.usr-is-merged 02/11/2025 07:59 PM 2,424,984 init 09/27/2024 03:13 PM <DIR> srv 11/23/2024 08:12 PM <DIR> mnt 03/07/2025 11:42 AM <DIR> proc 03/07/2025 11:42 AM <DIR> dev

In Linux, your Windows disk letters appear as subdirectories of /mnt

ls -ltr /mnt total 0 drwxrwxrwx 1 gilbert gilbert 4096 Mar 7 11:16 d drwxrwxrwx 1 gilbert gilbert 4096 Mar 7 11:16 c drwxrwxrwx 1 gilbert gilbert 4096 Mar 7 11:16 e drwxrwxrwt 2 root root 60 Mar 7 11:48 wsl drwxrwxrwt 7 root root 300 Mar 7 11:48 wslg

While /home/username is your Linux home directory, when you run a Linux program from Windows then the program starts in the same current directory that Windows had, expressed through the mapping:

C:\Users\gilbert>wsl gilbert@MWPFxxxxx:/mnt/c/Users/gilbert$

When you go from Windows to Linux, your Windows Environment variables are merged with Linux environment variables.

In Linux, if you type a command that turns out to be a *.exe program, the Microsoft Linux Kernel handles the transition from Linux back to Windows. At this time there is no way for Windows to automatically recognize a Linux program, so you have to run “wsl <programname>”. However, you can create a programname.bat file somewhere in your Windows path. For example, grep.bat could contain:

wsl grep %*

and then when you run the “grep” command in Windows it will run the Linux program with all the same arguments.

Installation

You can install WSL and the distribution from the Windows Store in Windows 11. However, there is no Store in Windows Server 2025, so you might as well get used to the command line.

Windows 11 Home Edition is not licensed to allow use of the full Hyper-V. There is a limited function “no configuration” version of Hyper-V that gets installed to run WSL.

If WSL is not installed, just run the Windows command

wsl --install

This command installs the minimal Hyper-V feature, then downloads and installs the Microsoft Linux Kernel, and then downloads and installs the default Ubuntu distribution. You typically then have to reboot to enable everything.
To list the other available distributions (without using Store), type the Windows command

wsl --list --online

Some WSL Implementation Internals

Bell Labs created Unix when computers were big expensive machines shared by users. One people switched to using networks of smaller computers, they started work on a successor to Unix with a codname of “Plan 9”. The idea was to make a network of PCs look like a single system with a lot of users. Files on different computers would appear to be one big file system, and programs and servers running on different machines would look like they were all running in one operating system. To make this work, they developed a very powerful network-based disk sharing and program to program communication protocol named “9P”.

Microsoft adopted 9P as a way to combine the Windows OS (disks, files, programs) with a Linux OS so that the combination of two systems looked to the user like a single tightly integrated system. However, the Microsoft adaptation of 9P runs between a logged in Windows user and the WSL Linux VM started by that logged in user.

While Windows and Linux assume that everything is private by default and a user has to explicitly share disks or directories with the network, the 9P model is that everything is shared by default and something is private by setting permissions. This aligns with the view that while you are logged into Windows and running WSL, your Windows programs have full access to everything on your personal copy of a WSL distribution, and WSL programs you run have access to anything on Windows that you (the currently logged in user under which WSL is running) have access to.

WSL originally ran in single user mode (like a Docker container). Then Microsoft added support for systemd by adding an option in the /etc/wsl.conf file in the WSL distribution file system. Ubuntu defaulted to enabling systemd after 23.10.

WSL has some complicated rules for networking that require their own section.

The Distros

Microsoft provides the Hyper-V feature and the Linux Kernel.

Various suppliers provide WSL Distributions in the form of a tar file containing a file system. While the “wsl --install <distroname>” command will download and install a distro from the Microsoft library, you can get a tar file from some other source and create a distro from it.

The non-Docker container that runs a distro stores its files in a Hyper-V virtual disk (*.vhdx) file somewhere in the C:\windows directory. Changes made while the distro runs are written to the virtual disk and persist (whereas Docker containers do not persist changes to their file systems).

Generally, the distro named “Ubuntu” is the same version as the most recent explicit named version (“Ubuntu-24.04” as this is written). You can create two separate versions of the latest version of Ubuntu distinguished by these two names. Each will have their own distinct files on separate virtual disks. If you need a third instance of Ubuntu, you need to “wsl --export” a tar file with a file system and then “wsl --import” the tar file you just generated, giving it a new distro name.

If you are inclined to create a distro from a Beta version of Ubuntu, they keep compressed tar files in a public Web site called https://cloud-images.ubuntu.com/releases/. Remember to unzip the file because “wsl --import” takes a tar and not a tar.gz file.

One distro is designated the Default. It is the distro you run when you type the “wsl” command without a distro name.

WSL Networking

This is a subject that is constantly being changed by Microsoft, but there are a few basic ideas that remain constant.

First, the “localhost” address of 127.0.0.1 behaves like a network adapter but it has nothing to do with the network. In both the Windows and Linux Kernels, localhost is implemented with a dummy device and a special device driver so that a client program can talk to a server program on the same computer without data ever going to any network.

There is support in both the Windows and Linux Kernel drivers for the dummy localhost devices that they know about each other and communicate using Hyper-V to create what amounts to a single coordinated localhost device across both systems. If two programs running in Windows and WSL both try to act as servers on port 8080, then one of them will get the port and the other will be told that the port is in use by someone else. Client programs on either Windows or WSL can then connect to localhost:8080 and talk to whichever server got the port. Data will be transferred as needed between the localhost drivers in the Windows Kernel and the Linux Kernel.

Experimentally (at the time this is being written) this behavior can also be extended to all the real network adapters in the Windows system. If network “mirroring” is enabled, the Linux Kernel creates a dummy Linux network adapter for every real Windows network adapter. It is experimental because Windows has to be in control, so Linux cannot attempt to reconfigure the network adapter to have different addressing or behavior. Client programs on either Windows or Linux can use an adapter to access servers on the real network, and server programs on Windows or Linux get a “first wins” resolution when they try to bind to an IP address and specific port number.

The default WSL network behavior is that the Linux Kernel creates one virtual network adapter that is connected to Windows, and Windows provides a NAT gateway through which client Linux programs in any Linux distribution can access the Internet. Linux server programs should bind to localhost as described above.

 

Related content