next up previous contents index
Next: The X Window System Up: bash Customization Previous: Aliasing

Environment Variables

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 programgif. 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;:

screen7099

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:

screen7110

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):

screen7113

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 gif. Those four variables are defined automatically when you login: you don't set them in your .bashrc or .bash_login.

;; figure7127
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:

screen7169

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 tex2html_wrap8352 , 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:

screen7183

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:

screen7187

Notice that my PATH does not have the current directory, ``.'', in it. If it did, it might look like this:

screen7191

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 involvedgif. 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:

screen7204

; 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:

screen7212

Without the curly braces, I would get nothing, since there is no environment variables named HOMEfoo.

screen7215

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:

screen7226

; 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.

screen7247


next up previous contents index
Next: The X Window System Up: bash Customization Previous: Aliasing

Converted on:
Mon Apr 1 08:59:56 EST 1996