Learning the Bash Shell

i-30a1e0366512a8ac50ae2cf969f02d73-learning_bash_shell.jpgFor the most part, computer operating systems all have a “shell.” When people talk about the “command line” … they are talking about the prompt in a shell. The concept of a shell, and the way we think of a shell today mostly stems from its implementation on Unix systems. A shell is a computer program that has a human interface and a number of built in or accessible functions (mostly other programs) that humans can invoke to make the computer do something. On ‘servers’ and on most computers back in the old days, the shell would typically appear as a prompt on a computer screen, and that would be all you would get. You type stuff in, and the computer types stuff as well, and between the two of you, stuff happens. On a computer with a graphical user interface (GUI), there is still a shell, but it looks different. The shell is less tangible to the human user, but the GUI itself is a program that provides the user interface, and it may either be the shell itself or it may be invoked automatically as the computer starts up by the shell.

Back in Windows 3.X days, the shell was called “Win” and there was a file on the computer that said, somewhere, “Shell=Win” or words to that effect. A neat trick to compensate for the fact that even then Windows was over-demanding of valuable hardware resources (memory and stuff) was to change this line so that it said “Shell=Word” … this was useful if you only wanted to run Word …. the windows desktop would not load, and thus not be using up resources. (Of course, you could run other programs by invoking them from within Word…. ah, the old days.)

One of the earliest Unix-type shells was called “sh” for “shell.” There were various shells, and for a time, shells competed with each other for dominance. At some point, I’m not sure how far back (maybe forever) a neat convention was worked into Unix/Linux systems such that if you invoked a shell different than the one you were using … like, if you wanted to run the korn shell and you were in the sh shell … you would just type the name of the new shell and that would replace, rather than run as a sub process in, the old shell. That is probably the least important thing you are going to learn today. Or all week, for that matter.

Somewhat more relevant is this question: What is the “BASH” shell? Well, there was a shell born of sh that was, and still is, called “Bourne” after it’s inventor, Stephen Bourne, in 1978. (No relation to Jason.) Later, yet another shell was developed based on Bourne, but better. Born of Bourne through the efforts of Brian Fox in 1987, the new shell was called “Born Again Shell” … or, for short, BASH. BASH was written as part of the GNU project, and is thus one of the key pieces of software that runs on Linux systems.

People will argue about this, but BASH is probably the best shell, the most modern shell, the coolest shell, for use in Linux. If you are going to learn how to use a shell, this is the shell to learn. In Ubuntu Linux, if you start a terminal, it will typically be a BASH shell that runs.

Learning the bash Shell (In a Nutshell (O’Reilly)) is an excellent, highly recommended introductory volume on BASH. It is one of a number of books that I would recommend for anyone who wants to learn BASH. Many parts of this book are too rudementary for many who would have an interst … chances are if you want to learn bash programming, you probably already know enough to be slighly annoyed at a very introductory book. However, it also may be true that you have not been systematic and thorough in your coverage of bash. So, I recommend this book to anyone who cannot answer he following questions:

What is a path, where is your path stored, how do you change it on the fly, and how do you change it permanently?

How do you take a text file full of shell commands and make it into an executable file that you can run any time you want from the command prompt?

What is a ‘select’ command and why is it cool?

Considerer the following bash program:

if [-a $filename]; then
exit 0

1) What is wrong with the syntax of the second line? (Hint: The programmer has spaced something out)
2) What will this program do?
3) Why does the third line say “exit 0” and not “exit 1”?

If you know the answer to all of these questions, then you probably don’t need this book. If you know the answer to none of these questions, then you probably need this book. If you fall in between, then, well, that’s a tough decision.


  1. #1 Tony P
    February 23, 2008


  2. #2 Jim
    February 23, 2008

    For those stuck in a Windows world, cygwin allows you to use a BASH shell (and a lot of other things) within Windows. It’s a valuable tool for those of us who need to run Windows, but need something more powerful than DOS (unless you really like DOS, of course).

  3. #3 rpenner
    February 23, 2008

    I have to recommend that you switch to a monospaced font for code examples where spaces are important and you want people to know if your zero is a number. (Admittedly, I can’t figure out how to do that when

    ,  and  don't work for me in Preview.)
    Also, -a might work for what is built into bash, but -e or -f might fit your intent better, especially if you port your script to a shell which relies on an external binary to implement these sorts of tests.
    And why does your code fall off the end without an exit for the alternative case? This would make sense if this was the preamble to a script whose job it was to create the file one time only and signal success in the event it made the file or if the file was already there.
    And if what is coded is your intent, what's wrong with:
    test -e $1 && exit 0
    There is something wrong with my example, but it is not the syntax. (It is the differnce between computer science (best way) and electrical engineering (least keystrokes to make it work this time).)
  4. #4 Greg Laden
    February 23, 2008

    All excellent suggestions. I’ll address each of them in my next post on the topic.

    I hope to have a CSS style appropriate for code as well.

    One quick thing for now: The main syntax error in my code is the lack of spaces after the “[” and before th e “]}

    This is interesting. There needs to be a space before and after the [ because [ is a command in bash … it is not punctuation. The closing ] on the other end is required (I think) in order to make the command structure excessively obscure. Kind of a joke, really.

    So test -e $1 && exit 0 is like [ -a $filename ] because [ means ‘test’ in bash.

    test -e $1 and [ -a $filename ] are the same kind of command because test = [ and they do the same thing because $1 is a parameter, and in my code, you would enter a filename. So if my program was named “isit” the one might enter on the command line:

    isit document.txt

    and if document.txt exists, then absolutely nothing happens (a standard *nix result). But the value returned would be 0, so my command could be used in another bash program like this:

    if isit document.txt …

    and if the document.txt file exists, the if statement gets a zero, which in bash means “yes” or “true.”

    Rpenner: It was very bad of me to not have the alternative (if the file does not exist) return a ‘1’ … which in bash means “no” or “false”

    Crap, I’ve said more than I want to…

  5. #5 peter
    February 24, 2008

    #!/usr/bin/env bash

    since bash may live elsewhere…

  6. #6 Citizen Z
    February 24, 2008

    Greg, for code snippets you can surround them with either the HTML <sample> or <code> tags. That should change the default font in most browsers automatically, and they’re valid HTML tags.

  7. #7 Greg Laden
    February 24, 2008

    Citizen: Ha, “code” worked. I had thought it would not given prior experience…

    Looks pretty good, too.