How does the new "Bash on Windows 10" really work?

I read online that Ubuntu and Bash are coming to Windows 10. I also read that it's not an emulator or virtual machine running on top of Windows, but something else. So how exactly does it all come together? And is it really going to be as stable and user friendly as Bash in Ubuntu?


Solution 1:

It's not an emulator in the same way that WINE Is Not an Emulator. That is to say, they've added a Linux kernel interface to their Windows kernel. When an app tries to use the Linux kernel, it gets translated into a Windows native system call and any responses from the kernel is translated into a native Linux response. So the app thinks it's running on a Linux kernel and hence doesn't need to be modified.

However, this is purely a Windows technology so if you want more details, you should get them from a Windows support group or something. Windows continues to be a proprietary OS, so I would expect a limited amount of details.

And is it really going to be as stable and user friendly as bash in ubuntu?

From an Ubuntu perspective, we're simply running on a primitive Linux kernel, comparable to running a modern desktop on a primitive X server. If you're only using the features supported by the fake kernel, then it'll be stable and user friendly. If you use unsupported features, it'll be unstable.

It will not be anywhere near a complete Ubuntu experience any time soon.

Solution 2:

For those curious as to how the Windows Subsystem for Linux (WSL) works and how it runs native Linux ELF-64 binaries, we've published a series of blog posts and accompanying videos explaining the WSL architecture, processes, syscalls, and filesystem support.

Scott Hanselman also did a great walkthrough video covering the installation process and how to configure Bash on Ubuntu on Windows:

HTH

Solution 3:

A quite old question that I came across today when someone asked if there was a general "What is WSL" question here somewhere. This is probably the closest (and first) of that nature here.

But I do believe it needs an updated answer here in 2021 to be relevant.

So some history to bring us up to date:

  • When this question was asked, and the feature originally announced, it was known as "Bash on Ubuntu on Windows and the underlying Windows Subsystem for Linux." Canonical and Microsoft worked closely together to develop the feature.

    @Jo-ErlendSchinstad's excellent answer above makes the great point that the original WSL (now called "WSL1") worked by "translating" Linux kernel/API calls into (closely) corresponding Windows API/kernel calls.

    And @RichTurner of the WSL team (who has my deepest appreciation for his and their work) provides some links with more information at the time. The real piece of interest that he points out, IMHO, is the ability of WSL to allow executing Windows binaries (commonly .exe's) directly within the Linux shell, with incredible support for console output, redirection, etc. You can run the Windows ipconfig.exe (or any command in powershell.exe, etc.), pipe it to Linux grep (or awk, etc.), and display the results. Unfortunately, I'm coming up with horribly over-simplified examples here that don't exhibit this features real usefulness.

    You can even launch Windows graphical applications from the WSL/Linux shell. More recently, Microsoft has used this feature to provide integrated Visual Studio Code launching from within WSL. You can code . to open the current (Linux) directory in (Windows) VSCode. Or code ~/.bashrc to edit your startup config. And oh so much more.

    And by default WSL automatically mounts any Windows drives under /mnt/c /mnt/d, etc. So you have the ability to work with "Windows" files from Linux. (But not, until later, the other way around.)

    At the time, bash.exe and ubuntu.exe were the primary ways to start up WSL and get to the Bash shell. At this point (well, for the last several years), those have been relegated to "historical" commands (according to the Microsoft doc) and the recommended method is the much more flexible wsl.exe command.

  • Another note for the history lesson -- A point of confusion (especially in questions posted here on Stack sites) is that Canonical has called this feature "Ubuntu terminal" (even in doc still available today), and ... well ... some folks here get pretty upset when people call "Ubuntu" a "terminal". Just don't blame users you see using this terminology. It's, IMHO, Canonical's fault for the poor choice of words.

    Perhaps the "terminal" moniker was meant to inform the user that WSL was "command-line only". There was no built-in X server, and thus no way out-of-the-box to run graphical Linux apps in WSL. That said, it was possible to install a third-party X server in Windows.

    A related "terminology dispute" is that nowadays, Ubuntu is installed from the Microsoft Store as an "App". So don't be surprised if you see some people call it the "Ubuntu App", even though you and I know it's an "operating system/OS". ;-)

  • Skipping forward in time, after the initial release, more distributions started to become available other than just Ubuntu. And, of course, people realized that you weren't limited to Bash (I was a Zsh user at the time, now a Fish convert). So the feature itself that this question originally asked about is now really known as "Windows Subsystem for Linux" (WSL) with the "Ubuntu" distribution installed in it.

    So it's a bit of a misnomer nowadays to talk about Ubuntu Bash on Windows, but you still see it used since it was the original name. Even the most popular WSL subreddit is still the historically-named r/bashonubuntuonwindows, even though it covers all of WSL in general (any distribution, any shell).

  • One additional jump forward for WSL in general was the exposure of the WSL filesystem in a pseudo-network share. So, for instance, files for the "Ubuntu" distribution can be accessed in Windows via \\wsl$\Ubuntu. This is great, but it does sometimes confuse new users who might edit (a.k.a. "corrupt") their ~/.bashrc using Notepad in Windows, which creates Windows line-endings (CRLF) rather than Unix/Linux-standard LF-only.

  • I'm sure there were some developments in the intervening years that I'm glossing over here, but the next big milestone for WSL occurred as the team prepared and (in 2020) released "WSL2". Here's a good comparison of the differences.

    The biggest difference is that, unlike the original WSL (now WSL1), WSL2 does run virtualized with a real Linux kernel (source available here). This opens up a lot of additional features, but one of the biggest is the ability to run containers (e.g. Docker) directly within WSL2.

    While the kernel is real, most of the hardware (e.g. network interfaces) is virtualized. So while you can do things like create TAP/TUN network devices, you need to join these to the virtual NIC. You wouldn't be able to, for instance, bridge two real NICs running under Windows from within WSL2 using brctl.

    The speed increase of WSL2 is pretty substantial as well, although I've never personally done any direct comparisons between "real Ubuntu" on the same hardware as "WSL2". Because WSL2 operates on an ext4 filesystem on a virtual HDD (ext4.vhdx), file operations on that filesystem are especially performant.

    That said, using the /mnt/c type of mounts (using the 9P protocol) under WSL2 is drastically slower than WSL1. So it's recommended to keep all files that you are going to edit within WSL2. Either that, or keep a copy of a WSL1 installation around (which is very easy) to do Windows filesystem work.

  • At this time, the "next big thing" planned in Windows 11 is WSLg, which allows execution of Linux graphical apps.

    Windows 11's WSL is also currently planned to have:

    • Easier support for WSL installation and upgrading (wsl --install)
    • The ability to mount additional physical and virtual drives in the instance
    • GPU support, so CUDA-type applications can run within WSL.

And what's next after that? I have no idea myself, but personally I'm hoping for some level of Systemd support. WSL currently uses its own /init for setting up the interop between Windows and Linux, such as those network interfaces and mounts I mentioned earlier. Unfortunately, quite a few Linux apps (and especially docs) assume Systemd support. That said, it's entirely possible to work around the lack of Systemd if you understand what you are trying to do. But it does throw a lot of new WSL users for a loop.