Going Native: Using the Windows Subsystem For Linux
Dance with who brung ya
The more and more I play with SQL Server on Linux, or using containers (and orchestration tools like Kubernetes), the more I have come to realize how much I enjoy the Unix/Linux shell environment. And the more I come to enjoy bash (or any native *nix user shell), the more I realize: the shell experiences in Windows… kind of stink.
Listen, before you take up pitchforks folks, let me be clear: scripting languages in Windows are pretty great, PowerShell especially. But as a shell experience, it’s kind of lacking. If you spend a lot of time in Visual Studio code authoring scripts, and then having those scripts run (interactively or otherwise), it’s totally fine. Acceptable, even.
And maybe that’s good enough, but usually it isn’t: that’s why we almost always rely on third party applications like PuTTY or MobaXTerm to handle our connections to any remote system that requires SSH. These applications have connection managers that can make managing frequently used connections a little easier, and also give you the ability to import/export keys, but are they any good?
The snob in me says: no, not really. Using other operating systems like Mac OS X or any desktop/server Linux experience provides a much better and native shell to work in. Wouldn’t it be great if there was a much better and on-par shell experience you could use in Windows that would give you a native bash shell to play with? Well, then I’ve got good news for you, and that’s the fact that you can do better.
Speaking my language
Microsoft has provided a native Linux experience for Windows, called the Windows Subsystem for Linux, or WSL. If you haven’t heard of this feature yet, here’s the short version of what this means:
“Install” a Linux distribution of you choice into your Windows 10 environment, which
Enables you to run common Linux command line tools, like grep and sed, which is something your Linux using friends and co-workers have been bragging about since like, forever, and
Gives you access to other Linux applications and commands, available via your chosen distribution’s package manager, and oh before I forget
Gives you an honest-to-goodness native SSH shell experience on your machine without the need for a third party application
Sounds cool, right? Well, it is. And getting started is pretty easy, too. Let’s walk through setup. I should mention that this technology is only available on the later(ish) builds of Windows 10, so upgrade already.
To get started, crack open a PowerShell command window (as Administrator) and run the following command:
This will enable the Windows feature that lets you install your distribution of choice, and you shouldn’t need a reboot (but hey, you never know). Once it’s done, it’s time to choose which Linux distribution you want to use as a base. Go ahead and knock the dust off of your Microsoft Store icon, and search for, say Ubuntu. Here’s what I get when I do it on my machine:
You’ll notice you get a few choices. Each version of Ubuntu varies (there were some big changes between 16.04 and 18.04, and if you’re not sure what to pick, I’d say stick with 16.04). Click the one you want and click “get.” This will download all the bits you need.
We’re almost done now, but we need to “initialize” the environment with a one-time setup, which includes creating your local user and password. This is a non-root user, but you can still sudo your way to the top with it. Just make sure you remember the username and password you create.
Once this setup is complete, you’re ready to rock and roll.
The best of Linux, on Windows
Why is this so much better than a third-party shell experience? Let’s take a a quick spin of some of the cooler features
Yup, that’s right: you don’t need a to rely on PuTTY anymore. Once you’re running this native subsystem, you get that distro’s version of ssh, along with all the other OpenSSH tools, like scp. And you can manage all your public/private keys separate from what you have set up in Windows, too.
Other cool Linux tools, without the need for a pesky VM
Did you ever want to have commands like curl, sed, tail, and other super common linux commands available to you on your local machine? Well, you do now. These shells come with a host of common Linux commands already installed, and you can use them within your local profile or any file on your Windows installation, as well (see below).
Oh, and if the tool or command you want isn’t installed be default, your local package manager can probably get it. If you installed Ubuntu, just use apt-get to find what you need. You know, like on an actual Linux installation.
Take, as a for instance, good ol’ trusty nmap. It doesn’t come as part of the install but it’s super useful, so how can we install it? Just like any other Ubuntu package, with apt:
Pretty great, right? This goes for just almost any tool you want to install locally, too (and full disclosure, nmap doesn’t work in WSL (yet), I’m just using it as a simple apt example).
Access to your Windows file system
By now, if you’ve got this installed and messed around a little bit, you may be wondering: where’s all my files? That’s because this small shell is using a file system buried deep in your profile’s local AppData folder. And if you start browsing around inside your shell, you might not realize that you can actually break out of your seemingly-isloated sandbox into your Windows file system.
From your shell, if you change your directory over to the /mnt folder, and list the contents…
You can see every drive letter on your PC. Navigating deeper…
Yup, that’s my C: drive alright. And I can use my native Linux commands there, too. You may hit some strange permission errors when you’re attempting to browse certain directories or open files, but hey, that’s what sudo is for. What could go wrong?
Conclusion: Get comfortable with Linux from the comfort of Windows
The thing is: I want a good shell-based experience. It has to work well, and I don’t just mean “it connects to a server and shows a prompt.” I want as close to a native experience as I can find. The WSL ticks these boxes for me. Not only does it give me a much more friendly, native SSH experience, it tacks on all kinds of other great utilities that any system administrator can love, too.
And this is just the beginning, because WSL2 is on the horizon, which promises even better compatability and new features that sound pretty cool too.
I highly encourage you to give it a shot!
Bonus: beautify your new shell
If you’ve followed along during this tutorial on your own, you might be wondering: “Drew, why does your shell not look like mine? Yours looks like Ubuntu!” Well, that’s because I made it that way. And you can too! I’m going to walk you through how, real quick, because I believe you deserve a pretty shell experience.
Once you’ve got it downloaded, drag the fonts over to your font’s folder (or font settings window) to get them installed.
Next, launch your Ubuntu shell. We’re going to set the font manually. Why manually? Well, because until you change something in these settings, there’s no place to automate the rest of our changes. From your newly installed fonts, pick “Ubuntu Mono.”
Now with that out of the way, I’m going to save you a whole bunch of clicking and typing. The PowerShell script below will:
Go out to your current user’s registry settings and find the settings for your Ubuntu shell. The problem here is that depending on what version of Ubuntu you installed, and when you installed it, your key name will have a version string attached to it. Which makes this really hard to automate. Fortunately, we can use the settings keys created when we set the font to grab the actual name. That’s what line 2 does with Get-ChildItem.
Next, we’re going to take that big chonkin’ registry name and get the actual entry as an object. Line 5 does this.
Now that we have this object, we’ll just keep piping it to Set-ItemProperty to set all the colors, highlights, and font sizes and weights to make this look like a base Ubuntu shell.
Here’s the code. Go ahead and drop this into VSCode, save it as a .ps1 file and run it (or run it from VSCode if that’s how you want to roll):
The script is pretty straight-forward: it’ll scan you local user keys for the Ubuntu shell, grab the properties, and add a bunch of settings in for the colors and font size and weight. The next time, you run your Ubuntu shell, it should look like this, with colors for everything including directories: