CMPSC
311,
Introduction to Systems Programming
Environment Variables, Part 1
Reading
- CP:AMA
- pp. 688-689, 765-766,
getenv()
- CS:APP
- Sec. 8.4.5, Loading and Running Programs
- Practice Problem 8.6
- Harley Hahn's Guide to Unix and Linux
- Ch. 12, Using the Shell: Variables and Options
- APUE, Sec. 7.5, Environment List; Sec. 7.9, Environment
Variables
- Solaris man pages
sh(1), the sections "Parameter Substitution"
and
"Environment"
csh(1), the section "Environment Variables and
Predefined Shell Variables"
environ(5), for a description of commonly-used
environment variables [man -s 5 environ]
- Linux man pages
environ(5) [man -s 5 environ]
exec(P), for the Posix section that describes
environ [man -a environ]
- Mac OS X man pages
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
- Identity
USER, HOME, LOGNAME, HOST
- Default programs
- Internationalization (examples to follow)
LANG, LC_ALL, LC_MONETARY, etc.
- Communication with software tools
CC, CFLAGS, LDFLAGS, MAKEFLAGS
- Command search path, directory list for file search
PATH (usually connected to the shell variable path
or PATH)
- etc.
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
echo VAR $VAR
- But, the results may differ between shells when
VAR
is not defined as an environment variable.
printenv
- print all the environment strings, one per line
- This is either a builtin shell command or the utility
program
/usr/ucb/printenv.
The which command will tell you.
printenv name
- if the environment variable
name is defined,
respond with its value, and set the exit status of the command
to
success (0)
- if not, respond with nothing, and set the exit status of the
command to failure (1)
- Note that "nothing" is different from "blank line", as will
be
seen in the examples.
C Shell (csh, tcsh)
setenv name value
unsetenv name
set
- list the shell variables, which are not the same as the
environment variables
Bourne shell (sh, bash)
set
- list the environment variables
name=value
export name
unset name
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)
- Depending on the system configuration, the console login
dialogue might allow you to choose a locale.
- In 2010, the PSU CSE lab configuration gave only three
locale choices:
C, POSIX, iso_8859_1.
% 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