CMPSC 311, Introduction to Systems Programming

Environment Variables, Part 1



Reading
See the previous discussion of main() for an introduction to environment variables.



Environment variables are maintained by the command interpreter and passed to each new process as it starts, via fork(), exec() and the system-supplied startup function.  The C Shell also maintains a set of shell variables, which are not passed to new processes.  The Bourne Shell maintains a set of keyword parameters, and you must specify which of them should be exported to a new process as its environment variables.

Environment variables are used to affect the behavior of functions, utility programs and application programs without explicitly passing them as parameters.  In this regard, they act like global variables in a program.



Examples of commonly used environment variables
Examples of environment variables with specific uses

function
environment variable
used for
catopen NLSPATH message catalog, name or location
LANG
default locale, for native language, etc.
fmtmsg
MSGVERB
message verbosity
tzset
TZ
time zone

utility environment variable used for
cd
CDPATH
directory names
HOME
home directory
(several)
TMPDIR directory for temporary files
man
PAGER
output filtering, default is more (or less)
read
IFS
internal field separator, lines from standard input in a shell script



You can use various shell commands to set and inspect your environment variables.  The exact syntax of this varies from shell to shell.  The command printenv will list all your environment variables, or just one.

The following examples all use Solaris.  You should get the same results on Linux or Mac OS X.

Any shell
C Shell (csh, tcsh)
Bourne shell (sh, bash)
Here is an example using the C Shell.  The environment variable FOO is not originally defined.  First we define FOO but with an empty value.  Then we define FOO with the value BAR, and finally remove its definition.  Although you can't see it because we omitted some of the output, the list of environment variables is not sorted.  FOO appears last on the list once it is defined, but it might have appeared at any position in the list, depending on the previous history of commands affecting the environment list.

% which printenv
printenv: shell built-in command.
% which setenv
setenv: shell built-in command.
% which set
set: shell built-in command.
% printenv

... (omitted for brevity; FOO does not appear in the list)
% printenv FOO
% echo $status
1
% setenv FOO
% printenv
...
FOO=
% printenv FOO

% echo $status
0
% setenv FOO BAR
% printenv
...
FOO=BAR
% printenv FOO
BAR
% echo $status
0
% unsetenv FOO
% printenv FOO
% echo $status
1
%

Be careful not to confuse the C Shell's builtin set and setenv commands.  set is used for shell variables, setenv is used for environment variables.

% unsetenv FOO
% printenv FOO
% /usr/ucb/printenv FOO
% set
... (omitted for brevity; FOO does not appear in the list)
% set FOO
% set
FOO    
...
% printenv FOO
% /usr/ucb/printenv FOO
% set FOO BAR
% set
BAR    
FOO    
...
% set FOO=BAR
% set
BAR    
FOO     BAR
...
% printenv FOO
% /usr/ucb/printenv FOO
% setenv FOO
% printenv FOO

% /usr/ucb/printenv FOO

% setenv FOO BAR
% printenv FOO
BAR
% /usr/ucb/printenv FOO
BAR

Here is a similar example using the Bourne Shell, started from the C Shell on Solaris (pay attention to the prompt).  Although you can't see it because we omitted some of the output, the list of environment variables is sorted, because the utility version of printenv decided to sort it.  FOO appears first on the list once it is defined and exported.  The lists given by printenv and the Bourne Shell builtin command set are different, because some shell variables are not exported to new processes.

% sh
$ which printenv
/usr/ucb/printenv
$ which setenv
no setenv in [list of directories from the path variable]
$ printenv
... (omitted for brevity; FOO does not appear in the list)
$ set
... (omitted for brevity; FOO does not appear in the list)
$ printenv FOO
$ echo $?
1
$ FOO=BAR
$ set
FOO=BAR
...
$ printenv
... (omitted for brevity; FOO does not appear in the list)
$ printenv FOO
$ echo $?
1
$ export FOO
$ printenv
FOO=BAR
...
$ printenv FOO
BAR
$ echo $?
0
$ unset FOO

$ printenv FOO
$ echo $?
$ exit
%

The Bourne Shell allows you to prefix a command with a name=value assignment, but the effect is different depending on whether the command is builtin or not (echo is builtin and printenv is not, for example).  We'll let you puzzle this one out.

% sh
$ echo FOO
FOO
$ echo $FOO

$ printenv FOO
$ FOO=BAR printenv FOO
BAR
$ printenv FOO
$ echo $FOO

$ FOO=BAR echo $FOO

$ echo $FOO
BAR
$ exit
%



The env utility is often useful if you want to control the environment of some program.

man page from Mac OS X

ENV(1)                    BSD General Commands Manual                   ENV(1)

NAME
     env -- set and print environment

SYNOPSIS
     env [-i] [name=value ...] [utility [argument ...]]

DESCRIPTION
     env executes utility after modifying the environment as specified on the
     command line.  The option name=value specifies an environmental variable,
     name, with a value of value.  The option `-i' causes env to completely
     ignore the environment it inherits.

     If no utility is specified, env prints out the names and values of the
     variables in the environment, with one name=value pair per line.

DIAGNOSTICS
     If the utility is invoked, the exit status of env shall be the exit sta-
     tus of utility; otherwise, the env utility exits with one of the follow-
     ing values:

     0       The env utility completed successfully

     1-125   An error occurred in the env utility.

     126     The utility specified by utility was found, but could not be
             invoked.

     127     The utility specified by utility could not be found.

COMPATIBILITY
     The historic - option has been deprecated but is still supported in this
     implementation.

SEE ALSO
     execvp(3), environ(7)

STANDARDS
     The env utility conforms to IEEE Std 1003.2-1992 (``POSIX.2'').

BUGS
     env doesn't handle commands with equal (``='') signs in their names, for
     obvious reasons.

BSD                             August 27, 1993                            BSD


man page from Solaris (lightly edited)

User Commands                                              env(1)

NAME
     env - set environment for command invocation

SYNOPSIS
     /usr/bin/env [-i | -]  [name=value...] [ utility [ arg... ]]

     /usr/xpg4/bin/env [-i |  -]   [name=value...]  [  utility  [
     arg... ]]

DESCRIPTION
     The env utility obtains the current environment, modifies it
     according  to  its arguments, then invokes the utility named
     by the utility operand with the modified environment.

     Optional arguments are passed  to  utility.  If  no  utility
     operand  is  specified, the resulting environment is written
     to the standard output, with one name=value pair per line.

  /usr/bin
     If env executes commands with arguments, it uses the default
     shell /usr/bin/sh (see sh(1)).

  /usr/xpg4/bin
     If  env  executes   commands   with   arguments,   it   uses
     /usr/xpg4/bin/sh (see ksh(1)).

OPTIONS
     The following options are supported:

     -i | -          Ignores the environment that would otherwise
                     be  inherited  from the current shell.  Res-
                     tricts the environment for utility  to  that
                     specified by the arguments.

OPERANDS
     The following operands are supported:

     name=value      Arguments of the form name=value modify  the
                     execution  environment,  and are placed into
                     the inherited environment before utility  is
                     invoked.

     utility         The name of the utility to be  invoked.   If
                     utility  names  any  of  the  special  shell
                     built-in utilities, the  results  are  unde-
                     fined.

     arg             A string to pass  as  an  argument  for  the
                     invoked utility.

EXAMPLES
     Example 1: Invoking utilities with new PATH values

     The following utility:

     example% env -i PATH=/mybin mygrep xyz myfile

     invokes the utility mygrep with a new PATH value as the only
     entry  in  its  environment.  In  this case, PATH is used to
     locate mygrep, which then must reside in /mybin.

ENVIRONMENT VARIABLES
     See environ(5) for descriptions of the following environment
     variables  that  affect  the execution of env: LANG, LC_ALL,
     LC_CTYPE, LC_MESSAGES, and NLSPATH.

     PATH     Determine the location of the utility. If  PATH  is
              specified as a name=value operand to env, the value
              given shall be used in the search for utility.

EXIT STATUS
     If utility is invoked, the exit status of env  is  the  exit
     status of utility. Otherwise, the env utility returns one of
     the following exit values:

     0        Successful completion.

     1-125    An error occurred.

     126      utility was found but could not be invoked.

     127      utility could not be found.

SEE ALSO
     ksh(1),   sh(1),   exec(2),    profile(4),    attributes(5),
     environ(5), standards(5)

SunOS 5.10           Last change: 2 Jan 2002                    3



Examples, from Solaris, at console (2008)
% locale
LANG=en_US.ISO8859-1
LC_CTYPE=en_US.ISO8859-1
LC_NUMERIC=en_US.ISO8859-1
LC_TIME=en_US.ISO8859-1
LC_COLLATE=en_US.ISO8859-1
LC_MONETARY=en_US.ISO8859-1
LC_MESSAGES=C
LC_ALL=

% locale -a
C
POSIX
en_CA
en_CA.ISO8859-1
en_US
en_US.ISO8859-1
en_US.ISO8859-15
en_US.ISO8859-15@euro
es
es_MX
es_MX.ISO8859-1
fr
fr_CA
fr_CA.ISO8859-1
iso_8859_1

% date
Thu Feb 14 16:45:24 EST 2008

% env -i date
Thu Feb 14 16:45:28 EST 2008

% env -i LANG=fr date
Thu Feb 14 16:45:42 EST 2008

% env -i LANG=fr_CA date
jeudi, 14 février 2008, 16:45:49 EST

% env -i LANG=fr_CA.ISO8859-1 date
jeudi, 14 février 2008, 16:45:58 EST
Examples, from Solaris, login via ssh (2008)

% locale
LANG=
LC_CTYPE="C"
LC_NUMERIC="C"
LC_TIME="C"
LC_COLLATE="C"
LC_MONETARY="C"
LC_MESSAGES="C"
LC_ALL=

% date
Thu Feb 14 16:40:10 EST 2008

% env -i date
Thu Feb 14 16:40:15 EST 2008

% env -i LANG=fr date
Thu Feb 14 16:40:30 EST 2008

% env -i LANG=fr_CA date
jeudi, 14 f?vrier 2008, 16:40:42 EST

% env -i LANG=fr_CA.ISO8859-1 date
jeudi, 14 f?vrier 2008, 16:41:02 EST

Examples, from Solaris, login via ssh (2012)

% locale
LANG=
LC_CTYPE="C"
LC_NUMERIC="C"
LC_TIME="C"
LC_COLLATE="C"
LC_MONETARY="C"
LC_MESSAGES="C"
LC_ALL=

% date

Thu Feb 16 15:40:18 EST 2012

% env -i date

Thu Feb 16 15:40:23 EST 2012

% env -i LANG=fr date

Thu Feb 16 15:40:27 EST 2012

% env -i LANG=fr_CA date

jeudi 16 f?vrier 2012 15 h 40 min 35 s EST

% env -i LANG=fr_CA.ISO8859-1 date

jeudi 16 f?vrier 2012 15 h 40 min 41 s EST

Examples, from Linux, login via ssh (2008)

% locale
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

% locale -a
(omitted, long list of available locale names)

% date
Thu Feb 14 16:27:00 EST 2008

% env -i date
Thu Feb 14 16:27:05 EST 2008

% env -i LANG=swedish date
tor feb 14 16:27:17 EST 2008

% env -i LANG=french date
jeu f?v 14 16:27:23 EST 2008

% env -i LANG=hungarian date
2008. feb. 14., cs?t?rt?k, 16.27.30 EST

% env -i LANG=romanian date
Jo feb 14 16:28:09 EST 2008

% env -i LANG=russian date
??? ??? 14 16:28:36 EST 2008

Examples, from Linux, login via ssh (2012)

% locale
[same as above]

% date

Thu Feb 16 15:42:51 EST 2012

% env -i date

Thu Feb 16 15:43:03 EST 2012

% env -i LANG=swedish date

tor feb 16 15:43:12 EST 2012

% env -i LANG=french date

jeu. f?vr. 16 15:43:21 EST 2012

% env -i LANG=hungarian date

2012. febr. 16., cs?t?rt?k, 15.43.31 EST

% env -i LANG=romanian date

joi 16 februarie 2012, 15:43:39 -0500

% env -i LANG=russian date

??? ??? 16 15:43:48 EST 2012

Examples, from Mac OS X, at console (2008)

% env -i LANG=fr_FR date
Jeu fév 14 16:36:07 EST 2008

% env -i LANG=fr_FR.ISO8859-1 date
Jeu f?v 14 16:36:14 EST 2008

% env -i LANG=fr_FR.ISO8859-15 date
Jeu f?v 14 16:36:23 EST 2008

% env -i LANG=fr_FR.UTF-8 date
Jeu fév 14 16:36:35 EST 2008

% env -i LANG=ru_RU.UTF-8 date
чт фев 14 16:59:34 EST 2008

% env -i LANG=hu_HU.UTF-8 date
Csü Feb 14 17:20:10 EST 2008

Examples, from Mac OS X, at console (2012)



Last revised, 15 Feb. 2013