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.
The answer is actually fairly simple. Subprocesses inherit only environment variables. They are available automatically, without the subprocess having to take any explicit action. All the other "things" -- shell options, aliases, and functions -- must be made explicitly available. The environment file is how you do this. Furthermore, only interactive shells process the environment file. The next two sections describe environment variables and the environment file, respectively.
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: HISTFILE, HOME, LOGNAME, PATH, PWD, OLDPWD, SHELL, and TERM.
It should be clear why these and other variables need to be known by subprocesses. We have already seen the most obvious example: text editors like vi and Emacs need to know what kind of terminal you are using; 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).
(varnames can be a list of variable names separated by whitespace.) If the names in varnames already exist, then those variables become environment variables. If they don't, the shell creates new variables that are environment variables.
With ksh, you may assign a value and export the variable in one step:
You can also define variables to be in the environment of a particular subprocess (command) only, by preceding the command with the variable assignment, like this:
You can put as many assignments before the command as you want. For example, assume 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:
TERM=trythisone emacs filename
emacs has trythisone defined as its value of TERM, yet the environment variable in your shell keeps whatever value (if any) it had before. This syntax is not very widely used, so we won't see it very often throughout the remainder of this book.
Nevertheless, environment variables are important. Most .profile files include definitions of environment variables; the sample .profile earlier in this chapter contained two such definitions:
EDITOR=/usr/local/bin/emacs SHELL=/bin/ksh export EDITOR SHELL
For some reason, the Korn shell doesn't make EDITOR an environment variable by default. This means, among other things, that mail will not know which editor to use when you want to edit a message. Therefore you would have to export it yourself by using the export command in your .profile.
The second line in the previous code is meant for systems that do not have the Korn shell installed as the default shell, i.e., as /bin/sh. 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.
3.5.2. The Environment File
Although environment variables are always known to subprocesses, the shell must be explicitly told which other variables, options, aliases, etc., are to be communicated to subprocesses. The way to do this is to put all such definitions in a special file called the environment file instead of your .profile.
The idea of the environment file comes from the C shell's .cshrc file; thus, many Korn shell users who came from the C shell world call their environment files .kshrc. (The rc suffix for initialization files is practically universal throughout the Unix world. It stands for "run commands" and entered the Unix lexicon by way of MIT's Compatible Time Sharing System (CTSS)).
As a general rule, you should put as few definitions as possible in .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 .profile are 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 Korn shell users who have tiny .profile files, e.g.:
stty stop ^S intr ^C erase ^? date from export ENV=~/.kshrc
(The from command, in some versions of Unix, checks if you have any mail and prints a list of message headers if you do.) Although this is a small .profile, this user's environment file could be huge.
There is an important difference between ksh88 and ksh93. In ksh88, the environment file is always executed. In ksh93, only interactive shells (those not reading from a script, but rather from a terminal) execute the environment file. Thus, it is best that the environment file contain only commands that are useful for interactive use, such as alias and option settings.
Another difference between the two shell versions is that ksh88 only does variable substitution on the value of ENV, while ksh93 does variable, command, and arithmetic substitution on its value. (Command substitution is described in Chapter 4. Arithmetic substitution is described in Chapter 6.)
Copyright © 2003 O'Reilly & Associates. All rights reserved.