This post has been adapted from a talk I originally gave at codebar, which is a non-profit initiative that facilitates the growth of a diverse tech community by running regular programming workshops. It is targeted to those who are learning to code.
This post is in two parts, a little history, followed by some live command line examples.
Way back in the 60s - 70s, computers were becoming more than just calculators.
They could save files to disk, have multiple running applications with multiple users, but these things are 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.
These shells have since evolved to be Windows desktop, Mac OS, all the touchy screeny bits of your phone etc. Basically all the user interaction stuff. They make your computer easy to use and (reasonably) hard to break.
But before these shells were pretty and graphical, they were command line. You would type something and get a response. They looked like this:
Here's a shell running the
cal command and printing out a calendar.
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?
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.
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
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
bash-3.2$ which echo /bin/echo
With Mac OS, we can even make the computer
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]
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,
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
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
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
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!