Understanding Unix shells and environment variables, Part 2

Unix Insider –

Unix shells come with variables that are used by the shell or related commands. In addition to variables that you create, the shell itself requires or takes advantage of variables that can be set up for it.

When you first log in to a Unix system, the

<font face="Courier">/etc/passwd</font>
file contains the name of the shell that is to be run for you. This appears in the last field of the password file. To see yours, type
<font face="Courier">cat /etc/passwd</font>
and pipe the result through
<font face="Courier">grep</font>
looking for your userid. In the example below I have used my id,
<font face="Courier">mjb</font>
.

<font face="Courier">$ cat /etc/passwd|grep mjb
mjb:500:500::/home/mjb:/bin/ksh
</font>

In this example, my logon runs the Korn shell. This shell reads and executes any existing file named

<font face="Courier">/etc/profile</font>
, which a system administrator has programmed for basic setup actions required for all users. After I execute
<font face="Courier">/etc/profile</font>
, I execute
<font face="Courier">$HOME/.profile</font>
. This is set up to contain my own environment. Both
<font face="Courier">/etc/profile</font>
and
<font face="Courier">$HOME/.profile</font>
set environment variables. The Bourne shell works in a similar fashion.

The C shell also takes a similar approach, but uses more files. It runs

<font face="Courier">/etc/csh.cshrc</font>
, then
<font face="Courier">/etc/csh.login</font>
, then an entire raft of files in your home directory, such as
<font face="Courier"> ~/.cshrc</font>
,
<font face="Courier">~/.history</font>
,
<font face="Courier">~/.login</font>
, and, finally,
<font face="Courier">~/.cshdirs</font>
.

Regardless of the approach, the result is an environment in which the user will run, including environment variables. You can see your environment variables by using

<font face="Courier">printenv</font>
or
<font face="Courier">env</font>
. The following is a short example of the output.

<font face="Courier">$ printenv
USERNAME=
HISTSIZE=1000
HOSTNAME=my.system.com
LOGNAME=mjb
MAIL=/var/spool/mail/mjb
TERM=xterm
PATH=/usr/bin:/bin:/usr/local/bin:/usr/bin/X11:/home/mjb/bin
HOME=/home/mjb
SHELL=/bin/ksh
PS1=[\u@\h \W]\$
</font>

Shells also use variables that are not part of the environment. For a description of the difference between shell and environment variables, see last month's column.

For example,

<font face="Courier"> PS1</font>
, listed above as an environment variable, is the prompt displayed on the screen when the shell is waiting for a new command. Another shell variable,
<font face="Courier">PS2</font>
, contains the prompt to be used when a command is begun but not completed before Enter is pressed. To see the prompt in use, type the commands below. The first echoes the
<font face="Courier">$PS2</font>
prompt to the screen. Then a new command is started with an opening parenthesis. The user presses Enter immediately and the shell waits for a command and a closing parenthesis. The shell displays the
<font face="Courier">></font>
prompt to indicate that it is waiting for more input. The command is entered and Enter is pressed. Once again, the
<font face="Courier">></font>
prompt is displayed, because the user has not yet closed the open parenthesis. Finally, the user types
<font face="Courier">)</font>
and presses Enter, ending the command.

<font face="Courier">$ echo $PS2
>
$ (
> cat /etc/passwd|grep mjb
> )
$ 
</font>

You can create a more graphic version of this by adding a command to change the

<font face="Courier">$PS2</font>
prompt. In the following example, the value of the
<font face="Courier">$PS2</font>
prompt is changed and the same command sequence is entered. The
<font face="Courier">$PS2</font>
prompt is reset.

<font face="Courier">$ echo $PS2
>
$ PS2="more please> "
$ (
more please > cat /etc/passwd|grep mjb
more please > )
$ PS2="> "
# echo $PS2
>
$
</font>

Why does the

<font face="Courier">PS2</font>
prompt have a value if it is not in the environment? Look at the
<font face="Courier">printenv</font>
listing and you will not see an entry for
<font face="Courier">PS2</font>
.

<font face="Courier">$ printenv
USERNAME=
HISTSIZE=1000
HOSTNAME=my.system.com
LOGNAME=mjb
MAIL=/var/spool/mail/mjb
TERM=xterm
PATH=/usr/bin:/bin:/usr/local/bin:/usr/bin/X11:/home/mjb/bin
HOME=/home/mjb
SHELL=/bin/ksh
PS1=[\u@\h \W]\$
</font>

The shell sets up some default shell variables;

<font face="Courier">PS2</font>
is one of them. Other useful shell variables that are set or used in the Korn shell are:

  • <font face="Courier">_</font>
    (underscore)
    -- When an external command is executed by the shell, this is set in the environment of the new process to the path of the executed command. In interactive use, this parameter is also set in the parent shell to the last word of the previous command.
  • <font face="Courier">COLUMNS</font>
    -- The number of columns on the terminal or window.
  • <font face="Courier">ENV</font>
    -- If this parameter is found to be set after any profile files are executed, the expanded value is used as a shell startup file. It typically contains function and alias definitions.
  • <font face="Courier">ERRNO</font>
    -- Integer value of the shell's
    <font face="Courier">errno</font>
    variable -- this indicates the reason the last system call failed.
  • <font face="Courier">HISTFILE</font>
    -- The name of the file used to store history. When assigned, history is loaded from the specified file. Multiple invocations of a shell running on the same machine will share history if their
    <font face="Courier">HISTFILE</font>
    parameters all point to the same file. If
    <font face="Courier">HISTFILE</font>
    isn't set, the default history file is
    <font face="Courier">$HOME/.sh_history</font>
    .
  • <font face="Courier">HISTSIZE</font>
    -- The number of commands normally stored in the history file. Default value is 128.
  • <font face="Courier">IFS</font>
    -- Internal field separator, used during substitution and by the read command to split values into distinct arguments; normally set to space, tab, and newline.
  • <font face="Courier">LINENO</font>
    -- The line number of the function or shell script that is being executed. This variable is useful for debugging shell scripts. Just add an
    <font face="Courier">echo $LINENO</font>
    at various points and you should be able to determine your location within a script.
  • <font face="Courier">LINES</font>
    -- Set to the number of lines on the terminal or window.
  • <font face="Courier">PPID</font>
    -- The process ID of the shell's parent. A read-only variable.
  • <font face="Courier">PATH</font>
    -- A colon-separated list of directories that are searched when seeking commands.
  • <font face="Courier">PS1</font>
    -- The primary prompt for interactive shells.
  • <font face="Courier">PS2</font>
    -- Secondary prompt string; default value is
    <font face="Courier">></font>
    . Used when more input is needed to complete a command.
  • <font face="Courier">PWD</font>
    -- The current working directory. This may be unset or null if shell does not know where it is.
  • <font face="Courier">RANDOM</font>
    -- A simple random number generator. Every time
    <font face="Courier">RANDOM</font>
    is referenced, it is assigned the next number in a random number series. The point in the series can be set by assigning a number to
    <font face="Courier">RANDOM</font>
    .
  • <font face="Courier">REPLY</font>
    -- Default parameter for the read command if no names are given.
  • <font face="Courier">SECONDS</font>
    -- The number of seconds since the shell started or, if the parameter has been assigned an integer value, the number of seconds since the assignment plus the value that was assigned.
  • <font face="Courier">TMOUT</font>
    -- If set to a positive integer in an interactive shell, it specifies the maximum number of seconds the shell will wait for input after printing the primary prompt (
    <font face="Courier">PS1</font>
    ). If this time is exceeded, the shell exits.
  • <font face="Courier">TMPDIR</font>
    -- Where the directory shell temporary files are created. If this parameter is not set, or does not contain the absolute path of a directory, temporary files are created in
    <font face="Courier">/tmp</font>
    .

The C shell uses variables with similar but lowercase names, such as

<font face="Courier">prompt1</font>
,
<font face="Courier">prompt2</font>
,
<font face="Courier">path</font>
,
<font face="Courier">home</font>
, and so on.

Other interesting variables are the locale setting variables. These variables are

<font face="Courier">LC_ALL</font>
,
<font face="Courier">LC_CTYPE</font>
,
<font face="Courier">LC_COLLATE</font>
, and
<font face="Courier">LC_MESSAGES</font>
.
<font face="Courier">LC_ALL</font>
effectively overrides the values for the other three LC variables; you can set them independently by not setting
<font face="Courier">LC_ALL</font>
.

  • <font face="Courier">LC_ALL</font>
    -- Determines the locale to be used to override any previously set values.
  • <font face="Courier">LC_COLLATE</font>
    -- Defines the collating sequence to use when sorting.
  • <font face="Courier">LC_CTYPE</font>
    -- Determines the locale for the interpretation of a sequence of bytes.
  • <font face="Courier">LC_MESSAGES</font>
    -- Determines the language in which messages should be written.

<font face="Courier">LC_ALL</font>
can be used to change the language for the system. Try the following sequence of commands below to see these in action. The language is changed to French (
<font face="Courier">fr</font>
) and
<font face="Courier">grep</font>
is invoked with an illegal option
<font face="Courier">-x</font>
. The error message appears in French. The
<font face="Courier">LC_ALL</font>
is set to Spanish (español, thus
<font face="Courier">es</font>
) and the error and error message are repeated. Finally
<font face="Courier">LC_ALL</font>
is unset and the error returns in English.

<font face="Courier">$ export LC_ALL=fr
$ grep -x
Usage: grep [OPTION]...PATRON [FICHIER]
Pour en savoir davantage, faites: 'grep --help'
$ LC_ALL=es
$ grep -x
Modo de empoleo: grep [OPCION]...PATRON [FICHERO]
Pruebe 'grep --help' para mas informacion
$ unset LC_ALL
$ grep -x
Usage: grep [OPTION]...PATTERN [FILE]
Try 'grep --help' for more information.
$
</font>
Top 10 Hot Internet of Things Startups
Join the discussion
Be the first to comment on this article. Our Commenting Policies