WSL 2 Tips

Windows Subsystem for Linux 2 which is now a fully backed kernel linked through underlying virtual machine tied into the hypervisor of the machine is a full linux kernel and environment, but it still sits inside of the Windows host which can make some debugging issues a little off.

First Point

If you install multiple linux environments on your machine how do you tell what they are and which one is the default?

wslconfig /l - List all the Window Subsystem for Linux installed on your machine


Windows Subsystem for Linux Distributions:
Ubuntu-20.04 (Default)

Here I have Ubuntu 20.04 as my default WSL instance and also WLinux (Pengwin)

There are several subcommands on the wslconfig command, listed here

Performs administrative operations on Windows Subsystem for Linux

    /l, /list [Option]
        Lists registered distributions.
        /all - Optionally list all distributions, including distributions that
               are currently being installed or uninstalled.

        /running - List only distributions that are currently running.

    /s, /setdefault <DistributionName>
        Sets the distribution as the default.

    /t, /terminate <DistributionName>
        Terminates the distribution.

    /u, /unregister <DistributionName>
        Unregisters the distribution.

Important one to know is to switch the default WSL instance type wslconfig /setdefault WLinux in this case to switch the default WSL instance to the Pengwin instance.  This means when you do the following command bash -c "lsb_release -a" from the host Windows machine you will use this linux environment.

No LSB modules are available.
Distributor ID: Debian
Description:    Pengwin
Release:        11
Codename:       bullseye

Second Point

This brings me around to my second tip that the bash.exe command can run commands directly from the target linux host by using the command argument of -c or command after calling the bash shell of the linux target environment.

This is important as trying to run a webserver (in this case golang and rust which started the server from http://localhost:8000 for instance) where giving me trouble as I am trying to access the server from a browser on the host windows machine and it kept trying to locate the windows host TCP host connection instead of the linux target environment.  It's because the Windows host does not know have a way to resolve the virtualized ip of the target linux environment, you should be using the assigned ip available here

bash -c "ip addr | grep -Ee 'inet.*eth0'"

Breaking it down

  • Call the linux bash shell bash
  • Run a command -c
  • Get the ip addresses ip addr
  • Find the internet eth0 interface this is the default ethernet interface assigned for the virtual machine grep -Ee 'inet.*eth0' the dash -Ee to grep means to use a regular expression to search the text contents in this case something that starts with inet. followed by any matching characters and ending with eth0

This will give you an output like so `

inet brd scope global eth0

And now you can take the above ip and use it as a substitute from the local Windows host OS to reach the running webserver on the target linux environment running internally as localhost

For example:

Configured for development.
    => address: localhost
    => port: 8000
    => log: normal
    => workers: 16
    => secret key: generated
    => limits: forms = 32KiB
    => keep-alive: 5s
    => tls: disabled
🛰   Mounting /:
    => GET / (hello)
🚀 Rocket has launched from http://localhost:8000

Can be accessed at on the local Windows host machine