Environment Variables

Every Unix process maintains a list of variables called the environment. When a new process is created, it inherits the environment from the process that created it (its parent process). For typical Unix commands, the parent is usually the shell process.

All environment variables are character strings, i.e. sequences of characters. There are no other data types such as integer, float, Boolean, etc. There are some shell features for treating variables as numbers, but their values are always stored as character strings. For this reason, numeric operations in the shell are very inefficient.

Since the shell creates a new process whenever you run an external command, the shell's environment can be used to pass information to any command that you run. For example, text editors, top, ls with colorized output, and other programs that manipulate the terminal screen, need to know what type of terminal you are using. Different types of terminals use different magic sequences to move the cursor, change the foreground or background color, 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, the new process inherits the shell's TERM variable, and uses it to look up the correct magic sequences for your terminal type.

PATH is another important environment variable which 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".

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

shell-prompt: printenv
BLOCKSIZE=K
COLORTERM=xterm-256color
DISPLAY=:0
HOME=/home/bacon
LANG=C.UTF-8
LOGNAME=bacon
PWD=/home/bacon
SHELL=/bin/tcsh
TERM=xterm-256color
USER=bacon
...
        

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 (sh, bash, dash, ksh, zsh), we use the export command:

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

Note

There cannot be any space before or after the '=', for reasons that will be clarified later.

For C shell derivatives (csh, tcsh), we use setenv:

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

Note

Setenv requires a space, not an '=', between the variable and the value.

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 program called rna-trans that uses OpenMP threads (multiple subprocesses running on separate cores to speed up the program) and he would like to run it using two cores. OpenMP normally uses all available cores, but we can limit it by setting the environment variable OMP_NUM_THREADS.

shell-prompt: env OMP_NUM_THREADS=2 rna-trans
        

Here, the env command sets OMP_NUM_THREADS, and then runs rna-trans. Since the rna-trans process is a child of the env process, it inherits the entire environment, including OMP_NUM_THREADS.

You can create environment variables with any name and value you like. However, there are many environment variable names that are reserved for specific purposes. A few of the most common ones are listed in Table 3.14, “Reserved Environment Variables”.

Table 3.14. Reserved Environment Variables

NamePurpose
TERMTerminal type for an interactive shell session
USERUser's login name
HOMEAbsolute path of the user's home directory (~)
PATHList of directories searched for commands
LANGCharacter set for the local language
EDITORUser's preferred interactive text editor

Example 3.36. Practice Break

shell-prompt: printenv | fgrep TERM
            

Practice

Note

Be sure to thoroughly review the instructions in Section 2, “Practice Problem Instructions” before doing the practice problems below.
  1. What is the environment in Unix?

  2. What data types are available for environment variables?

  3. Does a Unix process have any environment variables when it starts? If so, where do they come from?

  4. What is the purpose of the TERM environment variable? What kinds of programs make use of it?

  5. What is the purpose of the PATH environment variable? What kinds of programs make use of it?

  6. 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)

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