Fedora WSL

The best part of Windows is WSL...
A Linux fan

fedora-wsl-terminal-explorer-demo.png
The black window is the terminal on Windows 11 running WSL with Fedora 43. At the bottom, the Windows explorer.exe was started from WSL. Creating the file hello makes it visible on both sides, as they are looking at the same folder /home/sam/.

You are on Windows and you want to benefit from Linux without going all in ? Windows Subsystem for Linux (WSL for short), is the solution !

A lot of commands, tools or automations are just not available on Windows and you can get a pretty good experience of running a Linux machine for any kind of terminal usage.

You may also need to access complex dev environments that are so much easier to setup on Linux. Developing on VSCode (installed on Windows) is even possible. A deeper integration exists making it trivial to connect into WSL and install extensions.

A terminal at left showing make commands with arm-linux-gnueabihf-gcc. VSCode running at right, connected into WSL
Example of a complex dev environment for programming in assembly. Custom compiler toolchains, old dependencies, Qemu, and debugging required...

The goal of this guide is to help you get up and running with Fedora on WSL2, help you install a few basics tools and learn the basics of DNF. Optionnally, you might also be interested in installing a few productivity tools that will start to create a curiosity for the power of terminal usage.

What's WSL ?

It's like a Linux virtual machine but there is very deep integration between Windows and this VM, it is not isolated like traditionnals VM like in VirtualBox.

How much integration is there ?

  1. You can access files from both machines in both directions: access Windows files from Linux and vice-versa.
  2. There is a network mix: if you start a web server on port 3000, you should be able to access it in Firefox from Windows on localhost:3000.
  3. You can start GUI apps from WSL. If the app already exist on Windows (such as Firefox) it might not be needed, but when you develop GUI apps (like in Qt) you really need to start the app and see the results without recompiling on Windows...

Setup WSL with Fedora

Just open a Powershell window and copy paste the given commands

wsl --install FedoraLinux-43

If the name FedoraLinux-43 is not found, you probably have to update WSL to the latest version !

wsl --update

It will ask you to choose a username (choose something short to simplify your future usage) and a password. The username will be shown in your shell's prompt and used as the folder to your HOME directory, something like /home/joe.

If you have other WSL installations (Docker Desktop, WSL Ubuntu, etc), you might want to define the Fedora WSL as the default.

wsl --setdefault FedoraLinux-43 # define WSL Fedora as the default
wsl # to enter

Note: The wsl command only works in Windows, make sure you are running in cmd or Powershell and not directly inside Fedora.

If later on you need to change your username

wsl --manage FedoraLinux-43 --set-default-user <newusername>

If at some time you forget your password and cannot use sudo to reset it, you can login as root with this command.

wsl -d FedoraLinux-43 -u root

# If you need to change the password of user sam
passwd sam

Filesystems

As you have basically 2 OS, you also have 2 filesystems that are accessibles on both sides.

In WSL, the Windows files from the C: drive is accessible from /mnt/c/. On WSL, if you want to list files under your desktop folder, you can type ls /mnt/c/Users/joe/Desktop (considering the username is joe).

To try this feature, run this command in WSL to go into the Desktop folder from Windows.

cd /mnt/c/Users/joe/Desktop

Then you can run ls and you should see the same files that your Windows' desktop !

You can try to create a new empty file with touch hello.txt and looking at your Windows Explorer GUI you should see the new file.

Try to change the file in Notepad by adding hello there inside. Go back in your WSL terminal and run cat hello.txt, you should see the 3 worsd.

You can also You can also access the files from WSL in the Windows Explorer GUI. At left you should see an entry for that and you'll see the content of /. You users files are under /home/joe (considering your Linux's username is joe). The path shown in the Windows Explorer is something like \\wsl.localhost\FedoraLinux-43\home\joe.

The most important thing to remember is to avoid slow operations that use the filesystem from the other OS because there is a HUGE performance loss! If you are on WSL but you access files from Windows (anything under /mnt/c), if you try to copy files, run npm install, do any kind of compilation... if you take just forever to run !

Make sure to store your files under /home/joe and don't forget to backup these files when you do it for your Windows files!

Remember: if anything is very slow, think about if this issue. It could be the root of the slowness you are experiencing...

Learn DNF

DNF (the command dnf) is the main package manager on Fedora. You may know the equivalent on Ubuntu (apt) or on Arch (pacman). DNF is managing packages that are created using the RPM format (they have the .rpm extension), packages are usually named like that: bottom-0.9.5-1.fc40.x86_64 (package name - version - number - fedora version (here 40) - processor architecture (here x86_64)).

apt can be installed but cannot be used on Fedora because it has another package format (.deb) than Fedora.

DNF basics

DNF has many subcommands (dnf install, dnf remove, dnf search, etc), here a few examples you REALLY need to understand and remember.

dnf install

Let's start by installing a few tools to practice using this command.

First, you can install fastfetch, which is a nice way to gather important stats about your machine. This tool is available in the Fedora's registry, that is configured by default. Because of this, you just need to run this command to install it.

sudo dnf install fastfetch

This is what you should see, you can accept the installation with y. As you can see the fastfetch package has one dependency yyjson which is also installed.

> sudo dnf install fastfetch

Updating and loading repositories:
Repositories loaded.
Package                   Arch    Version                    Repository          Size
Installing:
 fastfetch                x86_64  2.44.0-1.fc43              updates          1.5 MiB
Installing dependencies:
 yyjson                   x86_64  0.11.1-1.fc43              updates        244.2 KiB

Transaction Summary:
 Installing:         2 packages

Total size of inbound packages is 646 KiB. Need to download 646 KiB.
After this operation, 2 MiB extra will be used (install 2 MiB, remove 0 B).
Is this ok [y/N]: y
[1/2] yyjson-0:0.11.1-1.fc43.x86_64          100% | 450.5 KiB/s | 109.5 KiB |  00m00s
[2/2] fastfetch-0:2.44.0-1.fc43.x86_64       100% |   1.2 MiB/s | 536.2 KiB |  00m00s
-------------------------------------------------------------------------------------
[2/2] Total                                  100% | 993.4 KiB/s | 645.7 KiB |  00m01s
Running transaction
[1/4] Verify package files                   100% | 181.0   B/s |   2.0   B |  00m00s
[2/4] Prepare transaction                    100% |   2.0   B/s |   2.0   B |  00m01s
[3/4] Installing yyjson-0:0.11.1-1.fc43.x86_ 100% |   9.2 MiB/s | 245.6 KiB |  00m00s
[4/4] Installing fastfetch-0:2.44.0-1.fc43.x 100% | 682.0 KiB/s |   1.6 MiB |  00m02s
Complete!

The command is using sudo because the files in the packages will be extracted in folders that can only changed by root (such as /usr/bin or /etc).

Then just run it with fastfetch and look what you could find as useful in the future: the kernel version, the processor model, the amount of RAM, etc...

Try to install other tools
Install figlet and lolcat by reusing the same command as before.

Solution
sudo dnf install figlet lolcat

As you can see, you can easily list several packages names at once !

And now you can have fun by running that !

figlet "Fedora is cool !" | lolcat

Here is the colorful result :)

figlet-lolcat-fun.png

Now, let's continue by installing cowsay! Do you like cows ?

Solution
sudo dnf install -y cowsay

The -y flag is used to ignore confirmation (think of it as "the yes mode").

dnf remove

Now, I admit I helped you install some useless tools. Happily, there is a way to uninstall these packages with dnf remove.

Can you guess the full command to remove the 3 useful packages ?

Solution
sudo dnf remove figlet lolcat cowsay

dnf search

The previous packages were easy to install because they have each one a simple name and a unique package with the same name. What if you want to install something a bit harder ? You know a few keywords about the tool but not the exact name ?

There is nice tool called fd, which is the alternative to the Unix find command, which has easy to remember options. The package name is not fd nor find, can you find what's the name ?

Solution

Searching for find gives us a long list but it contains the wanted fd-find package !

> dnf search find
Updating and loading repositories:
Repositories loaded.
 assetfinder.x86_64	Find domains and subdomains related to a given domain
 fd-find.x86_64	Fd is a simple, fast and user-friendly alternative to find
 fedfind.noarch	Fedora compose and image finder
 findutils.x86_64	The GNU versions of find utilities (find and xargs)
... a long list

A way to filter the output is to filter the lines with grep, to match the other keyword fd, which gives us only 3 results.

> dnf search find | grep fd
 fd-find.x86_64	Fd is a simple, fast and user-friendly alternative to find
 fdupes.x86_64	Finds duplicate files in a given set of directories
 jdupes.x86_64	Duplicate file finder and an enhanced fork of 'fdupes'

If you add the -C option (in dnf -C search), you will use the local cache of available softwares instead of refreshing the list of packages each time on each registry.

If you want to find a particular plugin of a big framework, such as Qt, you can search with multiple keywords.

There is multimedia plugin with Qt 6, can you search that ?

Solution

We were looking for qt6-qtmultimedia and this commands finds it!

> dnf -C search qt multimedia
Updating and loading repositories:
Repositories loaded.
Matched fields: name, summary
 mingw32-qt5-qtmultimedia.noarch	Qt5 for Windows - QtMultimedia component
 mingw32-qt6-qtmultimedia.noarch	Qt6 for Windows - QtMultimedia component
 mingw64-qt5-qtmultimedia.noarch	Qt5 for Windows - QtMultimedia component
 mingw64-qt6-qtmultimedia.noarch	Qt6 for Windows - QtMultimedia component
 phonon-qt4.x86_64	Multimedia framework api for Qt4
 phonon-qt5.x86_64	Multimedia framework api for Qt5
 phonon-qt6.x86_64	Multimedia framework api for Qt6
 qt-mobility-multimediakit.x86_64	QtMultiMediaKit support
 qt5-qtmultimedia.x86_64	Qt5 - Multimedia support
 qt5-qtmultimedia-devel.x86_64	Development files for qt5-qtmultimedia
 qt5-qtmultimedia-doc.noarch	Documentation for qtmultimedia
 qt5-qtmultimedia-examples.x86_64	Programming examples for qt5-qtmultimedia
 qt6-qtmultimedia.x86_64	Qt6 - Multimedia support
 qt6-qtmultimedia-devel.x86_64	Development files for qt6-qtmultimedia
 qt6-qtmultimedia-examples.x86_64	Programming examples for qt6-qtmultimedia
...

dnf provides

When you are running some kind of scripts and it fails with a command not found errors, you probably just have to install a specific DNF package that bring this command. But which package ? It can often be the same name as the command, except when it's not the case... DNF can help you find which package provides a given command (this is why it is named dnf provides).

Let's take an example with this error

Deploying boot files into the first partition...
./deploy.sh: line 94: mcopy: command not found
> dnf provides mcopy
Updating and loading repositories:
Repositories loaded.
mtools-4.0.48-1.fc43.x86_64 : Programs for accessing MS-DOS disks without mounting the disks
Repo         : fedora
Matched From :
Filename     : /usr/bin/mcopy

mtools-4.0.49-1.fc43.x86_64 : Programs for accessing MS-DOS disks without mounting the disks
Repo         : updates
Matched From :        
Filename     : /usr/bin/mcopy

The package that brings mcopy is mtools so you can just sudo dnf install mtools.

Installing from COPR

There is nice CLI called bottom with a btm command. If you check out the README of bottom, you'll see there are numerous ways to install it.

If you try to directly install it via dnf like before, it will fail with a No match for argument: bottom because the tool is not shipped in the connected DNF registries.

> sudo dnf install bottom
Repositories loaded.
Failed to resolve the transaction:
No match for argument: bottom
You can try to add to command line:
  --skip-unavailable to skip unavailable packages

You'll need to enable the COPR with the first command and then the bottom package will not be found

sudo dnf copr enable atim/bottom -y
sudo dnf install bottom

Setup Git and SSH authentication

To be able to clone, commit, push and pull Git repositories, you need to install and configure Git, which needs to have SSH authenticated setup to be able to connect with your account to the Git server.

Configure SSH

You have to generate a new SSH key pair with the command ssh-keygen. Leave the default path to store the key (here in /home/sam/.ssh/id_ed25519). You can define a passphrase or not, as you wish.

See example
> ssh-keygen
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/sam/.ssh/id_ed25519): 
Created directory '/home/sam/.ssh'.
Enter passphrase for "/home/sam/.ssh/id_ed25519" (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/sam/.ssh/id_ed25519
Your public key has been saved in /home/sam/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:wxTNDsNImCcZ/mS3GHPTUx5pmCbMMi0UU4Utm8dBYCA sam@sxp
The key's randomart image is:
+--[ED25519 256]--+
|    EB*X=Oooo.   |
|   .=.*o@oOoo.   |
|    .o=+=@oo.    |
|     + Ooo+.     |
|      o S.       |
|         .       |
|                 |
|                 |
|                 |
+----[SHA256]-----+

Then you can display the content of the public key with

cat ~/.ssh/id_ed25519.pub

and copy the full content in your Github's settings on https://github.com/settings, under SSH and GPG keys by creating a New SSH key.

Once that's done, you can verify the connection is working with the following command.

> ssh -T git@github.com
Hi samuelroland! You've successfully authenticated, but GitHub does not provide shell access.

You should then see your pseudo and this kind of message. Before this you may see the verification of the public key's fingerprint. You can go on this page of the GitHub docs about GitHub's SSH key fingerprints to verify it does matches to one of the entries. To easily compare the long strings, I recommend you to copy the string from your terminal, and paste that in your browser in the ctrl+f search bar. It there is match, it will be highlighted and you didn't needed to compare a dozens chars by hand...

Install Git

Now that SSH authentication is working, you have to install and configure Git.

sudo dnf install git -y

That's it ! Package managers are easy right ?

Configure the Git identity

You also need to indicate to Git which name and email you want to store in your commits. You can change those settings globally (notice the --global). You have to adapt to your name (the name on your GitHub account, or if you don't have one, just your username). I recommend the email you use it the noreply address provided by GitHub.

You can find this noreply address in your Emails settings:

github-settings-no-reply-email.png

git config --global user.name "Samuel Roland"
git config --global user.email 47849646+samuelroland@users.noreply.github.com

To verify it works, you can check the global configuration file for Git, it should contains the 2 entries name and email.

> cat ~/.gitconfig
[user]
	email = 47849646+samuelroland@users.noreply.github.com
	name = Samuel Roland

Now, I suggest to create a new private repository in Github, try to clone it, create a random file, commit it and push it. If the entire flow is working, you have a working Git setup.

Install Gitui

This part is optionnal, but this tool is AWESOME, if you are not convinced, please make me a favour, try it a few days and you'll like it. It takes a few tries to get used to the keyboard shorcuts.

Go see this cheatsheet on Gitui setup. Then go inside a Git repository and run gitui to start it.

Get Fish - the Friendly Interactive Shell

Fish is another AMAZING tool you will not regret to learn! It is extremly joyful without any plugin or customisations, and you can push it further if you learn just a bit more.

sudo dnf install -y fish

TODO continue documenting that another day

Using VSCode with WSL

VScode is well integrated with WSL, you can have a full dev environment in WSL and connect with VSCode installed on Windows !

Open VSCode from WSL

You like the code . command to open the current folder in VSCode ?

To enable this experience, the folder with the file code must be present in the PATH variable. This file is probably in /mnt/c/Users/joe/AppData/Local/Programs/Microsoft VS Code/bin where joe is replaced by your Windows username. It's important to take folder bin and not the parent containing Code.exe is not the same program. code is used to start Code.exe.

In Fish there is a nice tool called fish_add_path that allow to add a folder in the PATH it in a persistent manner.

So, you can run this command from WSL, once you adapted the folder path.

fish_add_path "/mnt/c/Users/joe/AppData/Local/Programs/Microsoft VS Code/bin"

Then going into you SYE folder and type code . should open it. The first time you might see this message, that's expected.

> code .
Updating VS Code Server to version f220831ea2d946c0dcb0f3eaa480eb435a2c1260
Removing previous installation...
Installing VS Code Server for Linux x64 (f220831ea2d946c0dcb0f3eaa480eb435a2c1260)
Downloading: 100%
Unpacking: 100%
Unpacked 2259 files and folders to /home/sam/.vscode-server/bin/f220831ea2d946c0dc...
Looking for compatibility check script at /home/sam/.vscode-server/bin/f220831ea2d...
Running compatibility check script
Compatibility check successful (0)
To read from stdin, append '-' (e.g. 'echo Hello World | code -')

You have to make sure you are actually running in WSL, by looking at the bottom left corner. If this is not written WSL:... but just >< this is not connected, even tough you might see your files.

vscode-inside-wsl.png

When clicking on this option you should see this kind of list where you can choose WSL.

vscode-remote-window-example.png

Install VSCode extensions running inside WSL

Given the extension ID like usernamehw.errorlens, you can install extensions adding the --remote wsl+Fedora flag in addition to the usual command.

code --remote wsl+Fedora --install-extension usernamehw.errorlens

Make sure to precise that everytime an extension needs to have access to local programs, if they are installed in WSL, as I don't mention this detail in the rest of my cheatsheets.