Any recent computer operating system (by recent, we mean since about 1970) has some sort of user interface—some way of specifying commands for the operating system to execute. But in lots of operating systems, that command interface was really built in and there was only one way to talk to the computer. Furthermore, an operating system’s command interface would let you execute commands, but that was about all. After all, what else was there to do?
The Unix operating system popularized the notion of separating the shell (the part of the system that lets you type commands) from everything else: the input/output system, the scheduler, memory management, and all of the other things the operating system takes care of for you (and that most users don’t want to care about). The shell was just one more program; it was a program whose job was executing other programs on behalf of users.
But that was the beginning of a revolution. The shell was just another program that ran on Unix, if you didn’t like the standard one, you could create your own. So by the end of Unix’s first decade, there were at least two competing shells: the Bourne Shell, sh (which was a descendant of the original Thomson shell), plus the C Shell, csh. By the end of Unix’s second decade, there were a few more alternatives: the Korn shell, (ksh), and the first versions of the bash shell (bash). By the end of Unix’s third decade, there were probably a dozen different shells.
You probably don’t sit around saying “should I use csh or bash or ksh today?” You’re probably happy with the standard shell that came with your Linux (or BSD or Mac OS X or Solaris or HP/UX) system. But disentangling the shell from the operating system itself made it much easier for software developers (such as Brian Fox, the creator of bash, and Chet Ramey, the current developer and maintainer of bash), to write better shells—you could create a new shell without modifying the operating system itself. It was much easier to get a new shell accepted, since you didn’t have to talk some operating vendor into building the shell into their system; all you had to do was package the shell so that it could be installed just like any other program.
Still, that sounds like a lot of fuss for something that just takes commands and executes them. And you would be right—a shell that just let you type commands wouldn’t be very interesting. However, two factors drove the evolution of the Unix shell: user convenience and programming. And the result is a modern shell that does much more than just accept commands.
Modern shells are very convenient. For example, they remember commands that you’ve typed, and let you re-use those commands. Modern shells also let you edit those commands, so they don’t have to be the same each time. And modern shells let you define your own command abbreviations, shortcuts, and other features. For an experienced user, typing commands (e.g., with shorthand, shortcuts, command completion) is a lot more efficient and effective than dragging things around in a fancy windowed interface.
But beyond simple convenience, shells are programmable. There are many sequences of commands that you type again and again. Whenever you do anything a second time, you should ask “Can’t I write a program to do this for me?” You can. A shell is also a programming language that’s specially designed to work with your computer system’s commands. So, if you want to generate a thousand MP3 files from WAV files, you write a shell program (or a shell script). If you want to compress all of your system’s logfiles, you can write a shell script to do it. Whenever you find yourself doing a task repeatedly, you should try to automate it by writing a shell script. There are more powerful scripting languages, like Perl, Python, and Ruby, but the Unix shell (whatever flavor of shell you’re using) is a great place to start. After all, you already know how to type commands; why make things more complex?