Another major thing one does in a .bashrc is set environment variables;. And what are environment variables? Let's go at it from the other direction: suppose you are reading the documentation for the program fruggle, and you run across these sentences:
Fruggle normally looks for its configuration file, .frugglerc, in the user's home directory. However, if the environment variable FRUGGLEPATH is set to a different filename, it will look there instead.
Every program executes in an environment;, and
that environment is defined by the shell that called the
program. The environment could be said to exist ``within'' the
shell. Programmers have a special routine for querying the
environment, and the fruggle program makes use of this routine.
It checks the value of the environment variable FRUGGLEPATH. If
that variable turns out to be undefined, then it will just use the
file .frugglerc in your home directory. If it is defined,
however, fruggle will use the variable's value (which should
be the name of a file that fruggle can use) instead of the
default .frugglerc.
Here's how you can change your environment in bash;:
You may think of the export command as meaning ``Please export this variable out to the environment where I will be calling programs, so that its value is visible to them.'' There are actually reasons to call it export, as you'll see later.
This particular variable is used by Phil Zimmerman;'s infamous public-key encryption program, pgp;. By default, pgp uses your home directory as a place to find certain files that it needs (containing encryption keys), and also as a place to store temporary files that it creates when it's running. By setting variable PGPPATH to this value, I have told it to use the directory /home/larry/secrets/pgp instead. I had to read the pgp manual to find out the exact name of the variable and what it does, but it is farily standard to use the name of the program in capital letters, prepended to the suffix ``PATH''.
It is also useful to be able to query the environment:
Notice the ``$''; you prefix an environment variable with a dollar sign in order to extract the variable's value. Had you typed it without the dollar sign, echo would have simply echoed its argument(s):
The ``$'' is used to evaluate environment variables, but it only does so in the context of the shell--that is, when the shell is interpreting. When is the shell interpreting? Well, when you are typing commands at the prompt, or when bash is reading commands from a file like .bashrc, it can be said to be ``interpreting'' the commands.
There's another command that's very useful for querying the environment: env;. env will merely list all the environment variables. It's possible, especially if you're using X, that the list will scroll off the screen. If that happens, just pipe env through more: env | more.
A few of these variables can be fairly useful, so I'll cover
them. Look at Figure . Those four variables are
defined automatically when you login: you don't set them in your
.bashrc or .bash_login.
;;
Figure: Some important environment variables.
Let's take a closer look at the TERM variable.; To understand that one, let's look back into the history of Unix: The operating system needs to know certain facts about your console, in order to perform basic functions like writing a character to the screen, moving the cursor to the next line, etc. In the early days of computing, manufacturers were constantly adding new features to their terminals: first reverse-video, then maybe European character sets, eventually even primitive drawing functions (remember, these were the days before windowing systems and mice). However, all of these new functions represented a problem to programmers: how could they know what a terminal supported and didn't support? And how could they support new features without making old terminals worthless?
In Unix, the answer to these questions was /etc/termcap;. /etc/termcap is a list of all of the terminals that your system knows about, and how they control the cursor. If a system administrator got a new terminal, all they'd have to do is add an entry for that terminal into /etc/termcap instead of rebuilding all of Unix. Sometimes, it's even simplier. Along the way, Digital Equipment Corporation;'s vt100; terminal became a pseudo-standard, and many new terminals were built so that they could emulate it, or behave as if they were a vt100.
Under , TERM's value is sometimes console, which is a vt100-like terminal with some extra features.
; Another variable, PATH, is also crucial to the proper functioning of the shell. Here's mine:
Your PATH is a colon-separated list of the directories the shell
should search for programs, when you type the name of a program to
run. When I type ls and hit , for example, the Bash
first looks in /home/larry/bin, a directory I made for storing
programs that I wrote. However, I didn't write ls (in fact, I
think it might have been written before I was born!). Failing to find
it in /home/larry/bin, Bash looks next in /bin--and there
it has a hit! /bin/ls does exist and is executable, so Bash
stops searching for a program named ls and runs it. There might
well have been another ls sitting in the directory
/usr/bin, but bash would never run it unless I asked for it by
specifying an explicit pathname:
The PATH variable exists so that we don't have to type in complete pathnames for every command. When you type a command, Bash looks for it in the directories named in PATH, in order, and runs it if it finds it. If it doesn't find it, you get a rude error:
Notice that my PATH does not have the current directory, ``.'', in it. If it did, it might look like this:
This is a matter of some debate in Unix-circles (which you are now a member of, whether you like it or not). The problem is that having the current directory in your path can be a security hole. Suppose that you cd into a directory where somebody has left a ``Trojan Horse'' program called ls, and you do an ls, as would be natural on entering a new directory. Since the current directory, ``.'', came first in your PATH, the shell would have found this version of ls and executed it. Whatever mischief they might have put into that program, you have just gone ahead and executed (and that could be quite a lot of mischief indeed). The person did not need root privileges to do this; they only needed write permission on the directory where the ``false'' ls was located. It might even have been their home directory, if they knew that you would be poking around in there at some point.
On your own system, it's highly unlikely that people are
leaving traps for each other. All the users are probably friends or
colleagues of yours. However, on a large multi-user system (like many
university computers), there could be plenty of unfriendly programmers
whom you've never met. Whether or not you want to take your chances
by having ``.'' in your path depends on your situation; I'm not
going to be dogmatic about it either way, I just want you to be aware
of the risks involved. Multi-user systems really are communities, where
people can do things to one another in all sorts of unforseen ways.
The actual way that I set my PATH involves most of what you've learned so far about environment variables. Here is what is actually in my .bashrc:
; Here, I am taking advantage of the fact that the HOME variable is set before Bash reads my .bashrc, by using its value in setting my PATH. The curly braces (``{...}'') are a further level of quoting; they delimit the extent of what the ``$'' is to evaluate, so that the shell doesn't get confused by the text immediately following it (``/bin'' in this case). Here is another example of the effect they have:
Without the curly braces, I would get nothing, since there is no environment variables named HOMEfoo.
Let me clear one other thing up in that path: the meaning of `` $PATH''. What that does is includes the value of any PATH variable previously set in my new PATH. Where would the old variable be set? The file /etc/profile serves as a kind of global .bash_profile that is common to all users. Having one centralized file like that makes it easier for the system administrator to add a new directory to everyone's PATH or something, without them all having to do it individually. If you include the old path in your new path, you won't lose any directories that the system already setup for you.
You can also control what your prompt looks like. This is done by setting the value of the environment variable PS1. Personally, I want a prompt that shows me the path to the current working directory--here's how I do it in my .bashrc:
; As you can see, there are actually two variables being used here. The one being set is PS1, and it is being set to the value of PWD, which can be thought of as either ``Print Working Directory'' or ``Path to Working Directory''. But the evaluation of PWD takes place inside single quotes. The single quotes serve to evaluate the expression inside them, which itself evaluates the variable PWD. If you just did export PS1=$PWD, your prompt would constantly display the path to the current directory at the time that PS1 was set, instead of constantly updating it as you change directories. Well, that's sort of confusing, and not really all that important. Just keep in mind that you need the quotes if you want the current directory displayed in your prompt.
You might prefer export PS1='$PWD>', or even the name of your system: export PS1=`hostname`'>'. Let me dissect that last example a little further.
That last example used a new type of quoting, the back quotes. These don't protect something--in fact, you'll notice that ``hostname'' doesn't appear anywhere in the prompt when you run that. What actually happens is that the command inside the backquotes gets evaluated, and the output is put in place of the backquotes and the command name.
Try echo `ls` or wc `ls`. As you get more experienced using the shell, this technique gets more and more powerful.
There's a lot more to configuring your .bashrc, and not enough room to explain it here. You can read the bash man page for more, or ask questions of experienced Bash users. Here is a complete .bashrc for you to study; it's fairly standard, although the search path is a little long.