8.3 The Bourne Again Shell (bash)

8.3.1 Environment Variables

A Linux system is a complex beast, and there's a lot to keep track of, a lot of little details that come into play in your normal interactions with various programs (some of which you might not even need to be aware of). Nobody wants to pass a bunch of options to every program that gets run, telling it what kind of terminal is being used, the hostname of the computer, how their prompt should look...

So as a coping mechanism, users have what's called an environment. The environment defines the conditions in which programs run, and some of this definition is variable; the user can alter and play with it, as is only right in a Linux system. Pretty much any shell will have environment variables (if not, it's probably not a very useable shell). Here we will give an overview of the commands bash provides for manipulating its environment variables.

set by itself will show you all of the environment variables that are currently defined, as well as their values. Like most bash built-ins, it can also do several other things (with parameters); we'll leave it to the bash(1) man page to cover that, though. Example 8-1 shows an excerpt from a set command run on one of the author's computers. Notice in this example the PATH variable that was discussed earlier. Programs in any of those directories can be run simply by typing the base filename.

Example 8-1. Listing Environment Variables with set

% set
PATH=/usr/local/lib/qt/bin:/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:
/usr/openwin/bin:/usr/games:.:/usr/local/ssh2/bin:/usr/local/ssh1/bin:
/usr/share/texmf/bin:/usr/local/sbin:/usr/sbin:/home/logan/bin
PIPESTATUS=([0]="0")
PPID=4978
PS1='\h:\w\$ '
PS2='> '
PS4='+ '
PWD=/home/logan
QTDIR=/usr/local/lib/qt
REMOTEHOST=ninja.tdn
SHELL=/bin/bash
% unset VARIABLE

unset will remove any variables that you give it, wiping out both the variable and its value; bash will forget that variable ever existed. (Don't worry. Unless it's something you explicitly defined in that shell session, it'll probably get redefined in any other session.)

% export VARIABLE=some_value

Now, export is truly handy. Using it, you give the environment variable VARIABLE the value “some_value”; if VARIABLE didn't exist, it does now. If VARIABLE already had a value, well, it's gone. That's not so good, if you're just trying to add a directory to your PATH. In that case, you probably want to do something like this:

% export PATH=$PATH:/some/new/directory

Note the use of $PATH there: when you want bash to interpret a variable (replace it with its value), tack a $ onto the beginning of the variable's name. For instance, echo $PATH will echo the value of PATH, in my case:

% echo $PATH
/usr/local/lib/qt/bin:/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:
/usr/openwin/bin:/usr/games:.:/usr/local/ssh2/bin:/usr/local/ssh1/bin:
/usr/share/texmf/bin:/usr/local/sbin:/usr/sbin:/home/logan/bin

8.3.2 Tab Completion

(Here comes something cool again.)

  1. A commandline interface means lots of typing.

  2. Typing is work.

  3. Nobody likes work.

From 3 and 2, we can determine that (4) nobody likes typing. Fortunately, bash saves us from (5) (nobody likes a commandline interface).

How does bash accomplish this wonderful feat, you ask? In addition to the wildcard expansion we discussed before, bash features tab completion.

Tab completion works something like this: You're typing the name of a file. Maybe it's in your PATH, maybe you're typing it out explicitly. All you have to do is type enough of the filename to uniquely identify it. Then hit the tab key. bash will figure out what you want and finish typing it for you!

Example time. /usr/src contains two subdirectories: /usr/src/linux and /usr/src/sendmail. I want to see what's in /usr/src/linux. So I just type ls /usr/src/l, hit the TAB key, and bash gives me ls /usr/src/linux.

Now, suppose there are two directories /usr/src/linux and /usr/src/linux-old; If I type /usr/src/l and hit TAB, bash will fill in as much as it can, and I'll get /usr/src/linux. I can stop there, or I can hit TAB again, and bash will show a list of directories that match what I've typed so far.

Hence, less typing (and hence, people can like commandline interfaces). I told you it was cool.