Maybe you've come across the acronym CLI before, and wondered what it meant. Or maybe you've opened up a DOS prompt, ran some executable, and wondered if it's antiquated technology. So why do we still develop executables that are intended to run via the command line?
I'll save you from the default response of obviously it's just easier for developers to make, and developers are just used to writing these. While those might be large contributing factors to why command line executables are built in place of a different User Interface, there's actually more to it than that.
Graphical User Interfaces
So what's the big deal with Graphical User Interfaces (GUI)? This is just a fad, right? Don't worry, I'm aware that this is not a fad, and there are probably just as many developers working on the GUI for most applications as there are working on back end these days. Not to mention the number of frameworks to help build appropriate GUIs is substantial. So why do we like using GUIs so much?
We tend to throw around terminology like User-Friendly and User Experience as just expected outcomes for how we should be designing our interfaces. However there's usually a balance that has to be struck, between how much functionality is exposed to the end user, and not overwhelming users that are just getting started. Recent development efforts tend to show functionality based on context to help with limiting the overwhelming amounts of functionality. However this tends to cater a lot of our functionality towards those that are not very experienced with the application.
While this makes the application more accessible to more users, we usually don't leave much time to build efficient and effective workflows made for the users that are well acquainted with the functionality. While additional features could be added to help, there's usually a more pragmatic approach to enable users to work with the application. So we build a toolbox to give users building blocks to help build out their own functionality. That's why most web based applications usually have an API associated with their original efforts. In applications usually built for software developers, this usually involves a command line executable.
There is a little bit of an overlap of Discoverability with Usability. However I think it's important enough to note the differences. Symbolism is a huge component of discoverability. An example of this would be how acquainted most of us are with an idea of what a button is. When I think of a button in a GUI application, they are usually square, have a drop shadow to appear 3d, and when clicked has a different appearance which gives the illusion as if it has been pressed. These visual cues often help users relate to buttons that we see and use in the real world like the elevator button.
This is often why I use the phrase "a picture is worth a thousand words." I also like to think that this is why remarks like "Users tend to not read when it comes to usability" exists. It stems from the fact that advances have been made in better uses of symbolism or users' adoption to existing symbols. The need to read instructions to understand how an application is supposed to behave has slowly dissipated. Look at something as simple as the Save icon which is just a floppy disk, a media that is no longer really relevant. However it probably would never actually be able to be phased out since it has this long historical form of symbolism that cannot easily be replaced.
Context is probably one of the harder items to quantify since this can mean a lot of different things to a lot of different people. We often relate the work we're doing with the visual cues at that moment. Keeping those visual cues straight in our heads tends to help keep our thinking focused. So working in Microsoft Word and coming back to the same User Interface helps keep our contexts in order. (I believe this to be true for most users.)
Command Line Interface
The qualities mentioned for using a Graphical User Interface can make ramp up trivial for the initial use of an application. After becoming fairly proficient with an application, however, you may use keyboard shortcuts, mnemonics, or other ways to gain efficiency in the UI. With one application, this tends to not be too much of a chore. But a few years and dozens of applications later, you might find yourself having different workflows to efficiently navigate your way through a suite of applications. This tends to overcomplicate matters and leads most developers to want to build tools to help them in this area.
A lot of functionality that is common for developers to use can be executed via a console application at the Command Line Interface (CLI). This usually allows for building blocks to help build into a rerunnable script. Manually running these building blocks helps test and build a workflow that is right for you. We often underestimate how typing some letters into a prompt and hitting Enter is actually extremely valuable. We take for granted the ability to just test a building block, have it execute, and then extrapolate from the results. This is often known as the read-eval-print-loop (REPL) and is a very handy tool in the developer's tool belt.
So building this from scratch tends to be a bit difficult. However, what I've found is that using these small pieces of functionality often enough tends to show the inefficiencies in my workflow and gives me an easy way to build a script that would work around these problems.
Randall Munroe's chart on xkcd is an interesting thought exercise on how efficient you can make use of your time:
It also should be noted that building tools for the command line interface tend to be faster and easier to work with than a GUI framework. It's why you'll find more developer tools and those engineered by colleagues. I often think that most code has to be pristine. However there are plenty of reasons why writing code for a particular circumstance is beneficial and that it can be ok as long as it's only used for its intended purpose. So, building console applications are great in that mindset.
An Example: Source Control
While everything above may sound really theoretical and doesn't really lead you to believe one way or another, this example may help convince you.
Many of you who write source code use some form of source control or version control. I've used source control for years, mostly using some sort of GUI to do my work. One common GUI that I worked with was Tortoise for svn and mercurial (hg). That UI was great: it would show my diff before I committed and show files statuses prior to commit. This all led me to believe that I had a fast and efficient workflow since it allowed me to spot check my changes and there were plenty of handy features at my disposal.
So for this example I'm going to create a repository, add a file with some contents, and then commit and push. While the creating of an initial repository isn't usually very common, the steps of making changes and commit are on the contrary very common. I'll be using Windows and TortoiseHg for the GUI portion of the workflows. There could be other implementations that have better workflows. This is merely used as an example to show differences in the default workflow.
First, we create the directory which involves using Windows Explorer.
Then select Create Repository Here.
Next, we fill out the details in the New Repository dialog.
Now let's add a file to my new repository.
We should now commit it.
Finally let's push the changes. A remote repository has yet to be set up to push to, but I'll include this step since it is a very common part of the central-repository workflow.
This is a basic workflow using a GUI, and you can see the need to jump between Notepad, Windows Explorer and TortoiseHg. While there are IDE (Integrated Development Environments) that attempt to consolidate these into one application, you are more likely to find a command line app than an IDE to integrate all the apps you need. It's often why editors like emacs and vim have strong correlations with running some sort of shell. Take a look at (Vim Quickfix) for an example.
Here's the same workflow in Windows Powershell. The same could be done in Bash or DOS. So please don't focus on the use of Powershell instead of (insert your favorite shell here).
There are benefits that come into play with this CLI approach. Not only are these steps most likely far quicker than switching applications, these steps are also a lot easier to reproduce either with someone following along at home, or a script that could be written to do these same commands over again. If it hasn't quite registered with you... this is quite an accomplishment. I can now have the same setup on multiple machines just by writing a script that performs the same set of actions.
So we've talked about Graphical User Interfaces (GUI), Command Line Interface (CLI), and discussed some of the differences.
- Usability trade off for less functionality
- Discoverability becomes more difficult
- Context helps with memory but becomes a deterrent when there are too many contexts to switch between
- Discovery of automated workflows is easier
- Easier to reproduce and repeat workflows, both for others and for youself
- Quicker to develop CLI apps so there are usually more tools
Really these are good reasons to try and become more proficient with the CLI so that you have these tools in your tool belt when you need them. If you haven't quite chosen a shell to become more proficient at and would like to learn more, my next post will give an introduction to Windows Powershell for software developers.