by Gitter

A Brief History of the Command Line

IUMrO2oqiTUKEDmzWGY94DPftQv3tK93UrCu

This post by Andy Trevorah, Engineer at Gitter, has been adapted from a talk that he originally gave at codebar, a non-profit initiative that facilitates the growth of a diverse tech community by running regular programming workshops.

This post is in two parts: a little history, followed by some live command line examples.

A Brief History

Way back in the 1960s — 70s, computers were becoming more than just calculators. They could save files to disk and have multiple running applications with multiple users. But these things were difficult to control and easy to break. Thankfully, there was a very smart idea to cover all these internal bits in a nice, usable shell.

8dQXHBemVAUp4xgVzFqgEHGyNjCsQT0usHBw

These shells have since evolved to be Windows desktop, Mac OS, and all the touchy screeny bits of your phone. Basically all the user interaction stuff. They make your computer easy to use and (reasonably) hard to break.

But before these shells started looking pretty and graphical, they were just a command line. You would type something in, and you would get a response. They looked like this:

z6KVS8d-ygTOk6nf25pzAas6NhWtxu01Iw8P

Here’s a shell running the cal command and printing out a calendar.

This particular shell is called bash which is short for “Bourne Again SHell” because before that there was the “Bourne Shell” by Stephen Bourne. Never let a software engineer name something that will end up lasting.

There’s a rich history of shells, and these “Unix style” shells began with Unix System 1’s shell in 1969. But even that was influenced by older programs such as RUNCOM. If you’ve ever noticed that some config files end in “rc” (e.g .vimrc), thats why.

If these shells have changed since the 1960s, then why do developers keep on using them?

eKIIYJsqGQIaqkkd7NRrKfNpWN2AirtM6ius

Because they haven’t really changed since the 60s. Graphical interfaces for your phone or computer fashionably change with every update (with usability improvements), but command line shells don’t. When you are scripting things or dealing with an entire farm of servers, you really don’t want your (user) interface to change, as it will break your scripts.

Thankfully, both command line and graphical shells are both shells around the same thing, so we can use them both interchangeably. Here’s some examples to show what command line shells can do.

Shells in Action

We can start small and just get the computer to repeat what we say:

bash-3.2$ echo hello  hello

The computer also has some special words like $RANDOM:

bash-3.2$ echo $RANDOM  23914

Bear in mind that almost all of these commands are just little programs that accept some input and emit output. You can find out where they are using which:

bash-3.2$ which echo  /bin/echo

With Mac OS, we can even make the computer say stuff:

bash-3.2$ say hello  ["hello" comes from the speakers]
bash-3.2$ say butts butts butts  ["butts butts butts" comes from the speakers without complaint]

There’s also cat which will print out file contents. It’s from 1971.

bash-3.2$ cat cool_websites.txt  Some websites that I like:
http://codebar.io  http://ocw.mit.edu/ans7870/6/6.006/s08/lecturenotes/files/t8.shakespeare.txt

We can use it to read some built in files on your computer:

bash-3.2$ cat /usr/share/dict/words  [skip a few thousand lines]zymotically  zymotize  zymotoxic  zymurgy  Zyrenian  Zyrian  Zyryan  zythem  Zythia  zythum  Zyzomys  Zyzzogeton

That’s every word that your computer knows! That list is pretty long (almost too long to scroll!), but we can use the head command to see the top of it:

bash-3.2$ head /usr/share/dict/words  A  a  aa  aal  aalii  aam  Aani  aardvark  aardwolf  Aaron

And there is an opposite command, tail:

bash-3.2$ tail /usr/share/dict/words  zymotoxic  zymurgy  Zyrenian  Zyrian  Zyryan  zythem  Zythia  zythum  Zyzomys  Zyzzogeton

It would be neat to just get the last word. tail can do this, but requires a special argument. We can look it up using man:

bash-3.2$ man tail
TAIL(1)                   BSD General Commands Manual
NAME       tail -- display the last part of a file
SYNOPSIS       tail [-F | -f | -r] [-q] [-b number | -c number | -n number] [file ...]
DESCRIPTION       The tail utility displays the contents of file or, by default, its stan-     dard input, to the standard output.
     The display begins at a byte, line or 512-byte block location in the     input.  Numbers having a leading plus (`+') sign are relative to the     beginning of the input, for example, ``-c +2'' starts the display at the     second byte of the input.  Numbers having a leading minus (`-') sign or     no explicit sign are relative to the end of the input, for example, ``-n     2'' displays the last two lines of the input.  The default starting loca-     tion is ``-n 10'', or the last 10 lines of the input.
     The options are as follows:
:

Ah! The argument is -n (you press “q” to exit the manual btw):

bash-3.2$ tail -n 1 /usr/share/dict/words  Zyzzogeton

I have no idea how to pronounce “Zyzzogeton”, but we can get the computer to do it using the say command. We just pipe the output of tail into the input of say using the pipe character (|):

bash-3.2$ tail -n 1 /usr/share/dict/words | say  ["Zyzzogeton" comes from the speakers]

Neat! We can even have multiple pipes. We can pipe cat into tail into say and get the same result:

bash-3.2$ cat /usr/share/dict/words | tail -n 1 | say  ["Zyzzogeton" comes from the speakers]

Now if we wanted to get a random word, we could get all the words up to a random point and then get the last word of that. We can do that with head and tail:

bash-3.2$ cat /usr/share/dict/words | head -n $RANDOM | tail -n 1 | say  ["atmological" comes from the speakers]

cat reads files from your hard drive, but we can use curl to read files from the internet. Here’s a url for a file that contains the full works of shakespeare:

bash-3.2$ curl -s http://ocw.mit.edu/ans7870/6/6.006/s08/lecturenotes/files/t8.shakespeare.txt  [skip a few thousand lines]  Would yet again betray the fore-betrayed,  And new pervert a reconciled maid.'
THE END
<<THIS ELECTRONIC VERSION OF THE COMPLETE WORKS OF WILLIAM  SHAKESPEARE IS COPYRIGHT 1990-1993 BY WORLD LIBRARY, INC., AND IS  PROVIDED BY PROJECT GUTENBERG ETEXT OF ILLINOIS BENEDICTINE COLLEGE  WITH PERMISSION.  ELECTRONIC AND MACHINE READABLE COPIES MAY BE  DISTRIBUTED SO LONG AS SUCH COPIES (1) ARE FOR YOUR OR OTHERS  PERSONAL USE ONLY, AND (2) ARE NOT DISTRIBUTED OR USED  COMMERCIALLY.  PROHIBITED COMMERCIAL DISTRIBUTION INCLUDES BY ANY  SERVICE THAT CHARGES FOR DOWNLOAD TIME OR FOR MEMBERSHIP.>>
End of this Etext of The Complete Works of William Shakespeare

If we used this curl as an input to our random word pipes, we can get the computer to quote us random lines of Shakespeare!

bash-3.2$ curl -s http://ocw.mit.edu/ans7870/6/6.006/s08/lecturenotes/files/t8.shakespeare.txt | head -n $RANDOM | tail -n 1 | say  ["The sister to my wife, this gentlewoman" comes from the speakers]

We can achieve quite a lot with only a few commands. This philosophy of having small reusable programs that can be combined together has lasted for a long time, much like lego bricks. By combining the right ones, you can make quite an impressive program!