The love hate relationship that is the command line and Windows. Anyone that has used Linux and has mastered the terminal, feels very unproductive on Windows. I for one feel like that. Too much clicking, give me a TUI (Text User Interface)!
Recently PowerShell gave Unix people new hope, that times are changing for the better. But are they? It’s definitely great leap forward, yet something is still missing. Microsoft gave us an awesome new shell, but I want more. I have felt the real power of a good command line, and I want it on Windows too.
What makes a perfect shell? It all starts with the terminal, the window that renders and displays the text from the shell. Next comes the shell, the most important piece of the equation, the thing that runs your commands. Finally comes the ecosystem of utilities and binaries that will be executed in the shell. Each element plays a critical role in the user experience.
The piece of software/hardware that is responsible for displaying the output of the shell. In the early days this was a monitor and a keyboard. Today, everything is done virtually via software, called a terminal emulator.
The terminal is the GUI that displays the text output of whatever you are running. It’s job is simple, it formats the text on-screen and sends keyboard/mouse events back to running application. Everything operates on a stream of characters, either in or out.
On Linux you have over a dozen of different terminal applications available to you, on Windows you have none. Yes, I said none. That’s because on Windows you don’t really have any terminal emulators. You only have an API and a primitive “terminal” like application, which only looks like a terminal.
Both cmd.exe, powershell.exe and some command line utilities operate by directly manipulating a API for rendering the text output in the “terminal”. This isn’t normally a problem if you like the standard “terminal” provided. But when you want to start using something else that’s when the problems arise.
The shells on Windows don’t operate on streams and pipes, which causes a lot of problems when you want to use something from the Unix world. Cygwin is an attempt to bring tools from Linux into the Microsoft world, unfortunately it has some major performance issues.
Even with cygwin and it’s issues, using both the Linux and Windows utilities together is a pain. Because of the architectural differences on how the console works, nasty hacks have to be used in order for them to coöperate. When using Windows tools within cygwin, a hidden console has to be opened to get the IO. Currently cmd.exe and most of its tools work, but powershell.exe does not (at least not in interactive mode). So using the terminal emulators (such as MinTTY or Xterm) provided by cygwin is useless.
There are two notable native terminals available on Windows, but they use the same nasty hacks which slow down performance. The applications I’m talking about are Console2 and ConEmu. ConEmu is a terminal on steroids, but it’s performance is unbearable when using Unix utilities (drawing is very slow).
So in short you cannot use all the fancy cool things that you have on Linux, such as readline, ANSI escape sequences, ncurses, the list goes on. You have to either be happy with the primitive terminal that Microsoft provides you, or just use cygwin tools exclusively (ie you cannot fully utilize PowerShell).
The foundation of a good command line is the shell. It’s where you will spend most of your time. It’s primary purpose is the execution of commands. But it should also be a powerful scripting engine at the same time. For years this was not available natively on Windows, not until PowerShell came out.
PowerShell brings a viable command line interface to Windows, with powerful scripting and automation capabilities that it desperately needed. Although its user experience in the interactive mode cannot be compared to bash (or any other well established Unix shell). On the other hand its scripting abilities are off the charts when it comes to automating and manipulating Windows.
I would say that PowerShell is more of a scripting language than a shell. It does function perfectly fine in interactive mode, but it’s no bash. This makes me cranky.
I’m very saddened by the interactive mode of PowerShell. I say this because the amount of typing and tabbing needed to achieve something is strenuous. Everything is very verbose, making typing commands laborious. On the flip-side everything typed into the shell is rather readable, even if you don’t know PowerShell.
Since I am very used to Unix command line utilities, not having them on Windows makes me very unproductive. Not being able to use sed, awk, cut, tr, less, cat, etc is very annoying. Unix philosophy for utilities is as follows: do one thing, but do it well, and make it pippable. So complex commands can be assembled using multiple commands pipped together. PowerShell fortunately has that functionality, but they do it in a completely different way.
The biggest innovation that PowerShell brings to the command line is that everything is an object. In bash or other shells, everything operates on a stream. This innovation enables you to do very interesting things. You can now pass on objects with attributes, making scripting much more powerful. Not to mention the ability to use C# and .NET within the shell.
As of version 3.0 of PowerShell, you can finally control the command line parser. For a bash person this is great, because via PSReadLine you can emulate the bash interface. Meaning you can have Emacs input mode, and tab completion just like in bash. This for me is a killer feature, and makes Windows usable.
The last part of the equation is the ecosystem of binaries and utilities available in the shell. Without it, there is no use in having a shell or terminal. It’s the bread and butter of the entire system.
This area was severely lacking in the Microsoft camp. You practically had nothing available in the console. You had old outdated binaries that were from the DOS age. PowerShell forced the creators of Windows to make every part of the OS accessible via the shell. And because of this we are now blessed with large array of “binaries”.
On Linux, on a typical distribution, you can have over 2000 binaries available to you in the shell. Not all of them are usable in the command line, but there are much more utilities available than on Windows. PowerShell bridges that gap by providing you cmdlets.
cmdlets are PowerShell’s command line “binaries”. They are the object aware utilities that you can use in the shell. Their name sets them apart from standard binaries, that only use steams. With each new version of Windows and PowerShell, you get more and more of these cmdlets.
So the ecosystem on Windows is starting to thrive, there is no shortage of binaries you can execute in your shell. But if you come from the Unix world, they will be completely different from what you are used to. Which makes using them a large learning curve.
Unix in Windows
So is it possible to have a good command line experience in Windows. Definitely Yes! It may not be what you want, coming from Linux. But it is a leap forward, from what it was.
Ever so often, when I come back to Windows, I feel more and more like I’m on Linux. Meaning it’s starting to fit my workflow, of doing everything from the keyboard. Once you start using the shell you wont look back. I certainly haven’t.
I’m curious what other people have to say about the state of the Windows command line. Please leave your thoughts and comments below.