Bash on Windows: Improving the Windows Command Line Experience
One of the more surprising reveals at Build 2016 was the effort by Microsoft to port native Bash to Windows.
Touted at “Bash on Ubuntu on Windows”, this is a surprising turnaround for a company whose former CEO once famously said that Linux is cancer.
Part of the reason for the shock is that when it comes to a command line interface, Microsoft tends to go against the grain. Between DOS and PowerShell, in the past, the company has had a different vision from the UNIX-like operating systems including various Linux distributions and OS X.
In addition, while there have been attempts to port these tools to Windows, each port brings with it a set of limitations that people looking for a consistent experience across different platforms run into.
This development means that developers on Windows will be able to fully participate in any type of development, regardless of the platform.
To help people get a sense of what this means for developing on Windows now, and in the future, I've put together a brief primer and overview.
First, Some Bash Clarifications
This isn't “Linux on Windows”, as Linux refers to the kernel of many operating systems such as Debian, Ubuntu (and derivatives), Fedora, etc. This also is more than just “Bash on Windows”.
Bash is a shell developed by the GNU project to replace the Bourne shell, and it is the default shell for most Unix-like operating systems. In addition to Bash, the features also include several other tools from userland.
Second, this isn't the only option for using these tools. Most developers are familiar with Cygwin; there's also MSYS, Git Bash, and GOW. All of those tools are great because they are compiled into the Windows kernel.
But to anyone who has ever worked with open source technology knows, these tools have limits, and you'll inevitably run into them. As a trivial example, trying to run Oh My ZSH on Cygwin — it doesn't work, since neither chsh or sudo are available.
For an example of more complex projects, attempt building some Ruby gems on Windows. It’s boggling the number of custom configurations and workarounds you’ll have to implement.
Laying the Bash Groundwork
These challenges were the primary motivation for the effort taken by the Windows team, for those working with open source technology.
As opposed to Cygwin or GOW, the tools provided in this update are not native Win32 applications; they are not compiled on Windows.
These tools are binaries directly from Ubuntu's repositories. In other words, they are “native” Linux applications. The technical details of how this is accomplished is a great read, and far beyond the scope of this article.
In the short version, this was accomplished by adding in the WSL (Windows Subsystem for Linux) and then using the work from Microsoft Research's Project Drawbridge to create the interface between the user's command and the actual binaries that are executed. (If you've got the time, I recommend reading some articles on it, they’re incredibly interesting!)
To install, you need to either have Fast Ring Insider updates enabled or wait for the Anniversary update that will be released in the summer of 2016. Once you have those, you need to enable the Windows Subsystem for Linux, and then run the bash command. An enhanced console will launch, and then you'll be prompted to create a new user. (This is because the security models between Windows and Linux are very different).
For the full details on a full installation walk-through, this article does a great job of outlining the step-by-step for you.
The Basics of Bash on Windows
If you’ve never (or rarely) used the command line, you might be a little disoriented when you first start. Some of the core commands include:
- MAN – The MANual command will display the manual page for any command you give. Very useful when you're trying to learn how to use a specific tool.
- PWD – Print Working Directory, this displays the directory where you are.
- LS – LiSt, this lists all the files in the directory. I typically will pair this with the -lFA arguments, which display more information about the files, and display various dot files.
- CD – Change Directory, this navigates you through the file system. If you execute it without an argument, it will move you back to your home directory.
- MKDIR – create a directory. If you need to create a set of nested directories, -p will create all the parent directories that don’t exist.
- RM – removes file.
- RMDIR – deletes empty directories. If you want to delete a directory with files, you execute ‘rm -rf’. Be very careful with this command; there is more than one story of a user mistyping the directory and losing all their files.
- TOUCH – this will update the access timestamp on a file. It’s useful when you have a program that operates on file timestamps. It’s also useful because if you execute it with the name of a file that hasn’t been created, it will create that file.
- CAT/LESS/MORE – These commands have differing uses, but they all share a common trait, which is the ability to display the contents of a file to the terminal without needing to open the file.
- GREP – If you've ever done a global find in Visual Studio, this is the command line equivalent. This tool will scan a set of files, looking for a given pattern, and then display those files which do that.
- FIND – This is one of the most useful tools that you can learn about. This command will search a given location for files that match any number of conditions. The name is the default choice, but the command can also find files modified within a specific timeframe.
- LOCATE – Similar to FIND, LOCATE will tell you the location of files. The difference is LOCATE does not need a directory to look for. Simply giving it the name of the file will cause it to display all the locations that file is present.
These tools support numerous command line arguments. Dig in to explore and experiment more with these tools. I recommend the handy explainshell.com site. You can paste (or type) the command in, and it will display a breakdown of the site.
However, rather than doing a random search on the internet, I'd recommend building the habit of reading the man pages provided by the tools. As a reminder, you access those by typing in MAN
One key advantage to mastering the command line is that it keeps your hands on the home row, so you don't have move your hand the mouse. This helps to improve your efficiency, and may help to alleviate some of those more pesky programming conditions, such as RSI and carpal tunnel.
The Advanced Commands
Learning and mastering the commands listed in the previous section are key to anyone who wants to use Bash as an interface to their computer, but there are a lot more commands to explore.
One of the more commonly used advanced commands would be sed, which can read text from any stream and transform it. This can be useful when you need to perform a find and replace on some text within a file. If you want to perform a similar search and replace on a set of files, you can pass sed into the exec argument of the find command.
Another powerful tool is awk, which can do text extraction and processing. This is useful if you’ve been collecting data in logs files and you’d like to use that data to generate a report.
Finally, Bash is more than just a shell programming for executing commands. It is has it’s own language that is commonly used to script out many tasks of an operating system. If you need to archive logs to preserve space, a shell command can typically do that.
Another concept to learn about are pipes, which in Unix-like systems are denoted by the | symbol.
Pipes allow you to take the output of one command and pass it into the input of another.
This enables you to chain commands together to execute complex tasks, like finding all the files that have been modified within 7 days, back them up to a directory, and then delete them.
Certain commands, like rm, cannot take in data from pipes. For those tools, xargs can be used.
Bash on Windows or Bust?
The introduction of Bash on Windows, it doesn’t mean you should cease learning PowerShell or stop using Cygwin.
Both those technologies have a place within your programming tool belt.
For developers who work with open source technology, Bash on Windows helps to smooth out the rough edges you run into when working with technology that was written primarily for Unix-like systems.
The command line is a very powerful tool to have available. Explore more and share what you find. I’d love to hear about some of your favorite core or advanced commands, that I didn’t get a chance to cover!