1.16. Environment Variables

Every Unix process maintains a list of character string variables called the environment. When a new process is created, it inherits the environment from the process that created it (its parent process).

Since the shell creates a new process whenever you run an external command, the shell's environment can be used to pass information down to any command that you run. For example, text editors and other programs that manipulate the full terminal screen need to know what type of terminal you are using. Different types of terminals use different magic sequences to move the cursor, clear the screen, scroll, etc. To provide this information, we set the shell's environment variable TERM to the terminal type (usually "xterm"). When you run a command from the shell, it inherits the shell's TERM variable, and therefore knows the correct magic sequences for your terminal.

The printenv shows all of the environment variables currently set in your shell process.

shell-prompt: printenv

Setting environment variables requires a different syntax depending on which shell you are using. Most modern Unix shells are extensions of either Bourne shell (sh) or C shell (csh), so there are only two variations of most shell commands that we need to know for most purposes.

For Bourne shell derivatives, we use the export command:

shell-prompt: TERM=xterm
shell-prompt: export TERM

For C shell derivatives, we use setenv:

shell-prompt: setenv TERM xterm

The PATH variable specifies a list of directories containing external Unix commands. When you type a command at the shell prompt, the shell checks the directories listed in PATH in order to find the command you typed. For example, when you type the ls command, the shell utilizes PATH to locate the program in /bin/ls.

The directory names within in PATH are separated by colons. A simple value for PATH might be /bin:/usr/bin:/usr/local/bin. When you type ls, the shell first checks for the existence of /bin/ls. If it does not exist, the shell then checks for /usr/bin/ls, and so on, until it either finds the program or has checked all directories in PATH. If the program is not found, the shell issues an error message such as "ls: Command not found".

Environment variables can be set from the shell prompt using the export command in Bourne shell and its derivatives (sh, bash, ksh):

shell-prompt: export PATH='/bin:/usr/bin:/usr/local/bin'

or using setenv in C shell and its derivatives (csh, tcsh):

shell-prompt: setenv PATH '/bin:/usr/bin:/usr/local/bin'

The env can be used to alter the environment just for the invocation of one child process, rather than setting it for the current shell process.

Suppose Bob has a script called rna-trans that we would like to run in his ~/bin directory. This script also invokes other scripts in the same directory, so we'll need it in our path while his script runs.

shell-prompt: env PATH='/bin:/usr/bin:/usr/local/bin:~bob/bin' rna-trans

1.16.1. Self-test

  1. What are environment variables?
  2. Does a Unix process have any environment variables when it starts? If so, where do they come from?
  3. How can environment variables be used to communicate information to child processes?
  4. Describe one common environment variable that it typically set by the shell and used by processes running under the shell.
  5. Show how to set the environment variable TERM to the value "xterm" in
    1. Bourne shell (sh)
    2. Korn shell (ksh)
    3. Bourne again shell (bash)
    4. C shell (csh)
    5. T-shell (tcsh)
  6. Show a Unix command that runs ls with the LSCOLORS environment variable set to "CxFxCxDxBxegedaBaGaCaD". You may not change the LSCOLORS variable for the current shell process.