Previous Section  < Day Day Up >  Next Section

3.5. Customization and Subprocesses

Some of the variables discussed above are used by commands you may run—as opposed to the shell itself—so that they can determine certain aspects of your environment. The majority, however, are not even known outside the shell.

This dichotomy begs an important question: which shell "things" are known outside the shell, and which are only internal? This question is at the heart of many misunderstandings about the shell and shell programming. Before we answer, we'll ask it again in a more precise way: which shell "things" are known to subprocesses? Remember that whenever you enter a command, you are telling the shell to run that command in a subprocess; furthermore, some complex programs may start their own subprocesses.

Now for the answer, which (like many UNIX concepts) is unfortunately not as simple as you might like. A few things are known to subprocesses, but the reverse is not true: subprocesses can never make these things known to the processes that created them.

Which things are known depends on whether the subprocess in question is a bash program (see Chapter 4) or an interactive shell. If the subprocess is a bash program, then it's possible to propagate nearly every type of thing we've seen in this chapter—options and variables—plus a few we'll see later.

3.5.1. Environment Variables

By default, only one kind of thing is known to all kinds of subprocesses: a special class of shell variables called environment variables. Some of the built-in variables we have seen are actually environment variables: HOME, MAIL, PATH, and PWD.

It should be clear why these and other variables need to be known by subprocesses. For example, text editors like vi and emacs need to know what kind of terminal you are using; the environment variable TERM is their way of determining this. As another example, most UNIX mail programs allow you to edit a message with your favorite text editor. How does mail know which editor to use? The value of EDITOR (or sometimes VISUAL).

Any variable can become an environment variable. First it must be defined as usual; then it must be exported with the command:[20]

[20] Unless automatic exporting has been turned on by set -a or set -o allexport, in which case all variables that are assigned to will be exported.

export varnames

(varnames can be a list of variable names separated by blanks). You can combine variable assignment and the export into one statement:

export wonderland=alice

It is also possible to define variables to be in the environment of a particular subprocess (command) only, by preceding the command with the variable assignment, like this:

varname=value command

You can put as many assignments before the command as you want.[21] For example, assume that you're using the emacs editor. You are having problems getting it to work with your terminal, so you're experimenting with different values of TERM. You can do this most easily by entering commands that look like:

[21] There is an obscure option, set -k, that lets you put this type of environment variable definition anywhere on the command line, not just at the beginning.

TERM=trythisone  emacs  filename 

emacs will have trythisone defined as its value of TERM, yet the environment variable in your shell will keep whatever value (if any) it had before. This syntax is surprisingly useful, but not very widely used; we won't see it much throughout the remainder of this book.

Nevertheless, environment variables are important. Most .bash_profile files include definitions of environment variables; the sample built-in .bash_profile earlier in this chapter contained six such definitions:

PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin

SHELL=/bin/bash

MANPATH=/usr/man:/usr/X11/man

EDITOR=/usr/bin/vi

PS1='\h:\w\$ '

PS2='> '

export EDITOR

You can find out which variables are environment variables and what their values are by typing export without arguments or by using the -p option to the command.

Some environment variable names have been used by so many applications that they have become standard across many shell environments. These variables are not built into bash, although some shells, such as the Korn shell, have them as built-ins. Table 3-9 lists the ones you are most likely to come across.

Table 3-9. Standard variables

Variable

Meaning

COLUMNS

The number of columns your display has[22]

EDITOR

Pathname of your text editor

LINES

The number of lines your display has

SHELL

Pathname of the shell you are running

TERM

The type of terminal that you are using


[22] Note that bash will set COLUMNS and LINES during certain situations, such as when the window the shell is in changes in size.

You may well find that some of these already exist in your own environment, most likely set from the system /etc/profile file (see Chapter 10). You can define them yourself in your .bash_profile and export them, as we did earlier.

3.5.1.1 Terminal types

The variable TERM is vitally important for any program that uses your entire screen or window, like a text editor. Such programs include all screen editors (such as vi and emacs), more, and countless third-party applications.

Because users are spending more and more time within programs, and less and less using the shell itself, it is extremely important that your TERM is set correctly. It's really your system administrator's job to help you do this (or to do it for you), but in case you need to do it yourself, here are a few guidelines.

The value of TERM must be a short character string with lowercase letters that appears as a filename in the terminfo database.[23] This database is a two-tiered directory of files under the root directory /usr/lib/terminfo. This directory contains subdirectories with single-character names; these in turn contain files of terminal information for all terminals whose names begin with that character. Each file describes how to tell the terminal in question to do certain common things like position the cursor on the screen, go into reverse video, scroll, insert text, and so on. The descriptions are in binary form (i.e., not readable by humans).

[23] Note that most modern UNIX systems now use a database rather than a flat file for the terminal descriptions.

Names of terminal description files are the same as that of the terminal being described; sometimes an abbreviation is used. For example, the DEC VT100 has a description in the file /usr/lib/terminfo/v/vt100. An xterm terminal window under the X Window System has a description in /usr/lib/terminfo/x/xterm.

Sometimes your UNIX software will set up TERM incorrectly; this usually happens for X terminals and PC-based UNIX systems. Therefore, you should check the value of TERM by typing echo $TERM before going any further. If you find that your UNIX system isn't setting the right value for you (especially likely if your terminal is of a different make from that of your computer), you need to find the appropriate value of TERM yourself.

The best way to find the TERM value—if you can't find a local guru to do it for you—is to guess the terminfo name and search for a file of that name under /usr/lib/terminfo by using ls. For example, if your terminal is a Hewlett-Packard 70092, you could try:

$ cd /usr/lib/terminfo

$ ls 7/7*

If you are successful, you will see something like this:

70092   70092A  70092a

In this case, the three names are likely to be synonyms for (links to) the same terminal description, so you could use any one as a value of TERM. In other words, you could put any of these three lines in your .bash_profile:

TERM=70092

TERM=70092A

TERM=70092a

If you aren't successful, ls will print an error message, and you will have to make another guess and try again. If you find that terminfo contains nothing that resembles your terminal, all is not lost. Consult your terminal's manual to see if the terminal can emulate a more popular model; nowadays the odds for this are excellent.

Conversely, terminfo may have several entries that relate to your terminal, for submodels, special modes, etc. If you have a choice of which entry to use as your value of TERM, we suggest you test each one out with your text editor or any other screen-oriented programs you use and see which one works best.

The process is much simpler if you are using a windowing system, in which your "terminals" are logical portions of the screen rather than physical devices. In this case, operating system-dependent software was written to control your terminal window(s), so the odds are very good that if it knows how to handle window resizing and complex cursor motion, then it is capable of dealing with simple things like TERM. The X Window System, for example, automatically sets xterm as its value for TERM in an xterm terminal window.

3.5.1.2 Other common variables

Some programs, such as mail, need to know what type of editor you would like to use. In most cases they will default to a common editor like ed unless you set the EDITOR variable to the path of your favorite editor and export it in your .bash_profile.

Some programs run shells as subprocesses within themselves (e.g., many mail programs and the emacs editor's shell mode); by convention they use the SHELL variable to determine which shell to use. SHELL is usually set by the process that invokes the login shell; usually login or something like rshd if you are logged in remotely. bash sets it only if it hasn't already been set.

You may have noticed that the value of SHELL looks the same as BASH. These two variables serve slightly different purposes. BASH is set to the pathname of the current shell, whether it is an interactive shell or not. SHELL, on the other hand, is set to the name of your login shell, which may be a completely different shell.

COLUMNS and LINES are used by screen-oriented editors like vi. In most cases a default is used if they are undefined, but if you are having display problems with screen-oriented applications then you should check these variables to see if they are correct.

3.5.2. The Environment File

Although environment variables will always be known to subprocesses, the shell must be explicitly told which other variables, options, aliases, and so on, are to be communicated to subprocesses. The way to do this is to put all such definitions into the environment file. bash's default environment file is the .bashrc file that we touched on briefly at the beginning of this chapter.

Remember, if you take your definitions out of .bash_profile and put them in .bashrc, you will have to have the line source .bashrc at the end of your .bash_profile so that the definitions become available to the login shell.

The idea of the environment file comes from the C shell's .cshrc file. This is reflected in the choice of the name .bashrc. The rc suffix for initialization files is practically universal throughout the UNIX world.[24]

[24] According to the folklore, it stands for "run commands" and has its origins in old DEC operating systems.

As a general rule, you should put as few definitions as possible in .bash_profile and as many as possible in your environment file. Because definitions add to rather than take away from an environment, there is little chance that they will cause something in a subprocess not to work properly. (An exception might be name clashes if you go overboard with aliases.)

The only things that really need to be in .bash_profile are environment variables and their exports and commands that aren't definitions but actually run or produce output when you log in. Option and alias definitions should go into the environment file. In fact, there are many bash users who have tiny .bash_profile files, e.g.:

stty stop ^S intr ^C erase ^? 

date

source .bashrc

Although this is a small .bash_profile, this user's environment file could be huge.

    Previous Section  < Day Day Up >  Next Section