Black Magic – Demystifying the Command Line Interface


In a previous post, I wrote about how I migrated to Linux after many years running Windows. For most computer users with longstanding Windows experience, one of the biggest gripes against Linux is that it is not user friendly. For many such people, the mentality is based on hearsay, but for some, it is based on actual experience: What do you mean sudo?


Few things strike fear into the hearts of modern Windows users like the CLI, and it’s easy to see why. Microsoft has come a long way with its flagship product, the Windows OS. Each new version has endeavored to give the user a more pleasant experience than the last. It’s primarily the reason for the product’s massive popularity, in spite of its price, security vulnerabilities and other flaws. The Windows desktop user has become accustomed to the easy life. Pointing and clicking is the system’s lingua franca. Application software developers have not “helped” the situation. Nearly every useful program, however cryptic, has a Windows GUI provided either by its vendor or by a third party in an effort to make it more accessible. These advances have gradually led to the misguided notion that the CLI is an extinct creature from the gruesome past of  computer evolution.

Pretending that the CLI does not exist is perfectly harmless for the average computer user. I would even go as far as recommending it. However, any power user or software developer who avoids the CLI is doing himself a huge disservice. I should know, I did for the longest time. The CLI opens up possibilities that no GUI could ever provide. It lets you perform long and tedious tasks quickly. It lets you automate repetitive tasks. It lets you work the same way across different flavors of Unix. It lets you get really intimate with the machine.


After running Linux as my primary OS for quite a while now, I thought I should share my experience and the lessons that I have learnt growing familiar with the CLI.

Linux is the opposite of Windows in many ways. While Windows prides itself in its user friendliness and accessibility, Linux is unapologetically geeky, preferring instead to be viewed as a lean and efficient powerhouse whose singular mission in life is to get things done. To be sure, many projects have evolved over the years with the goal of making Linux a more accessible, general purpose operating system. The most prominent example is without a doubt the ever so popular Ubuntu Linux by Canonical Ltd. Yet Linux can never quite seem to shed it’s heritage as a programmer’s plaything, and as with Windows, this culture pervades the entire ecosystem. There are many Linux programs with which interaction is only possible through the CLI or clunky, halfhearted graphical user interfaces.

A new Linux power user or software developer quickly discovers that unlike on Windows, there is no wishing away the CLI on Linux. The usual reaction is usually one of disbelief, even indignation. But eventually the cold, hard reality settles. Some take off, whimpering and kicking their way back to Windows. A few brave ones stay. If you  are staying, here are six tips to make your CLI journey less grueling and more fulfilling.

1. Do not attempt to memorize commands

Besides cd and ls, there aren’t many other commands that you should deliberately try to memorize. You should let your subconscious handle everything else. I find it does a pretty decent job of helping you remember the ones you use most. All the rest can always be easily found, even without any external reference. I will show you how, shortly.

2. Understand the anatomy of commands

Some commands appear cryptically long and impossible to remember. They are, so do not try to remember them. But they can be understood. Shell programs are written to do one thing and do it well. They read from standard input (keyboard), perform some processing and write to standard output (screen). Optionally, they have options, which in turn may take arguments. To achieve something more complex, commands may be chained together using pipes(|). Each subsequent command then gets its input from the output of the one preceding it. Input and output may also be redirected to other places besides standard input and standard output, to files for instance, using the greater than and less than characters (<, > and >>). Here’s a simple example:

echo cli is fun | cut -c1-3 >> cli.txt

In this example, we use 2 programs echo and cut. The echo program accepts input from the keyboard i.e. the line “cli is fun” and outputs the same to standard output. This output becomes the input of the the cut command. The cut command has one short option specified, -c, which may also be expressed as the long option –characters. For most modern programs, short options are prefixed with a single hyphen and long options are prefixed with double hyphens. Prefixing a long option with a single hyphen leads to expansion, so that cmd -option expands to cmd -o -p -t -i -o -n -s. The result is 7 different short options for the cmd command. In this case, the -c option takes an argument of the form N-M, meaning cut from the Nth character to the Mth character. The output of the cut command therefore becomes just “cli” and is appended to a file named cli.txt by way of output redirection.

Nearly all CLI commands conform to the above pattern. Some commands may require that you first specify a prompt i.e. a word that gives context to the command. For example, all Git commands such as add, commit and pull must be preceded by the prompt git, e.g. git add, git commit or git pull.

3. Know how to find help

As I already mentioned, you should not try to memorize CLI commands. Many CLI programs ship with detailed manual pages that explain what they do and how they should be used. The CLI provides some very handy programs that let you easily get help from right within the terminal. In my opinion, these are the first commands any CLI newcomer should learn.

type: tells you the type of a given command

whatis: gives you a short description of what a given command does

man: lets you access the entire manual page for a given command

apropos: searches names and descriptions of manual pages

help: display help for shell builtins

4. Use aliases

Much of the power of the CLI comes from the fact that simple commands can be chained together to do more complex things. After using the CLI for a while, everyone finds there are commands that they type often. Such commands, when long or difficult to remember, make good candidates for aliasing. Aliasing lets you invoke a command or chain of commands by typing a shorter, more memorable name. For example, to print my wireless LAN IP address I use:

ifconfig wlan | grep inet | grep -v inet6 | awk ‘{print $2}’

This is obviously unwieldy and unnecessary to memorize, so I have it aliased to a much shorter  name: ipad. I also have aliases for Git, Maven, SSH and many other commands that I run frequently.

5. Create functions

Sometimes it is the case that the set of commands you need are executed one by one rather than chained together and therefore cannot be aliased. Not a problem. Such commands can be defined inside a function and then the name of the function becomes the means by which to invoke them all at once. Shell functions are easy to write, even for people without much programming experience.

6. Write shell scripts

Tasks requiring more complex logic are best implemented in shell scripts. Shell scripts are fully-fledged computer programs designed to run in the shell. They can contain control structures and break down big tasks into functions that call each other to implement very complex logic. At the very basic level however, shell scripting is just yet another way of assembling simple programs in interesting ways to solve a big problem.

There you have it. Go on and have fun with the CLI. As a bonus, here are link to my favorite website for learning the Linux shell.

Related articles


Migrating from Windows to Linux: No Regrets


For about 2 years I had both Linux and Windows installed on my laptop. But having cut my teeth as a user and later as developer on a Windows environment, it is not surprising that I only booted the Linux installation on very few occasions – mostly when I was bored – and never really did anything useful with it. While I appreciated what looked like a decent desktop environment, I still preferred the familiar way of getting things done on Windows and the fact that I rarely ever needed to open the command prompt. In addition to that, about half of all the programming I did then was based on Microsoft’s tools so there wasn’t much professional motivation to pay attention to Linux.

Then I changed jobs and joined an organization where much of the development work going on was in Java and none of my two new teammates was writing it on a Windows platform. One guy was on Ubuntu Linux and the other one on MAC OS. More importantly, all software releases by the organization were made on VirtualBox appliances running Ubuntu. I started to worry that I would now not even be able to provide proper system support to users of our own software because it ran on an OS I was scarcely familiar with.

Making the Move

So I started thinking seriously about completely migrating to Linux. Fortunately, I got a new laptop around the same time and it shipped with Windows 8. My cumulative experience with Windows 8 to date is about 10 minutes. The 10 minutes between when I powered up the new laptop and when I decided the new desktop looked so different from Windows 7 that it felt as if I was learning to use a computer all over again. Well, almost. That was my watershed. If I was going to be spending time figuring out how to use a different environment, that environment might as well be Ubuntu’s Unity and of course, Linux in general. At that very moment, I downloaded Ubuntu 13.04 which, incidentally, was only a few hours old that day, and set it up as the only OS on my laptop. Phew! Besides having to disable the UEFI and tinkering a bit with ALSA to get sound coming out of the speakers, the installation was pretty straightforward and in about an hour, I had a working Linux system running on 4 cores and all of 16GB of RAM. How cool!

Still, there was the small matter of my unfamiliarity with the new OS. However, I felt that not having a familiar Windows OS to fall back to when things got tough was just the motivation I needed to get going. That’s how it turned out. After a couple of weeks of mucking about with terminal commands, a strange directory structure and a few other unfamiliar nuances of Linux, I felt even more competent and in control using it than I ever felt using Windows. I guess the pervasive sense of unfamiliarity and incompetence got me to deliberately study things in Linux that I only came to know by chance on Windows.

Exploring the Freedom

Within a few months of actively using Linux on a regular basis and also reading quite a bit of literature online, I started to marvel at the diversity of ways in which the OS was served up and in which you could consume it. For me, my installation of Ubuntu had been a lot like how one joins a religion early on in their lives. You get born into a Christian family and you become Christian. Then later on you grow up and form opinions of your own and you start to realize there are alternatives out there. And you start to become curious about them and to learn about them. Maybe you gather enough conviction and jump ship. Maybe you just change how you consume your original religion. Maybe you decide you don’t want to belong to any mainstream religion and you develop your own belief system… that would be Linux from Scratch 🙂

It turned out that the first casualty of my new-found freedom was the Unity desktop. KDE with their Plasma Desktop impressed me greatly the first time I tried it. Maybe it is the resemblance to Windows 7. You can never underestimate the power of familiarity. But more importantly, I felt a certain dislike for Unity. For instance, I hated the way menu bars docked up at the top, especially when I didn’t have my windows maximized. I also found that the KDE desktop appeared sleeker, elegant and more modern. With loads of RAM to spare, I didn’t worry about the fancy graphics impacting performance.

Lately I have been looking at the many distros available. I have a couple of them running on VMs on my system. I like the touted stability of Debian and the academic promise of Arch. Further down the road, as my competence increases, I want to try Linux from Scratch. Linux from Scratch is not really a distro. It is a book about how to make your own distro – just the way you want it. After all, it’s this kind of freedom that makes Linux and open source in general such a powerful and liberating idea.

As for now, I still pledge allegiance to my trusty Ubuntu installation… Kubuntu really, since I installed KDE. But I don’t think it will be like that for a long time. In a few weeks, it’s probably going to be Debian or OpenSUSE. Maybe it will be Debian then OpenSUSE. Then maybe Arch, and ultimately Linux from Scratch – the Mecca of the Linux enthusiast. But one thing is for sure, I will be using Linux for a long time to come.