Shell variables are variables whose scope is in the current shell session, for example in an interactive shell session or a script.
You may create a shell variable by assigning a value to an unused name:
The use of shell variables is to keep track of data in the current session. Shell variables usually have names with lower-case letters.
An environment variable is a shell variable which has been exported. This means that it will be visible as a variable, not only in the shell session that created it, but also for any process (not just shells) that are started from that session.
VAR="hello" # shell variable created
export VAR # variable now part of the environment
Once a shell variable has been exported, it stays exported until it is unset, or until its "export property" is removed (with
export -n in
bash), so there's usually no need to re-export it. Unsetting a variable with
unset deletes it (no matter if it's an environment variable or not).
Arrays and associative hashes in
bash and other shells may not be exported to become environment variables. Environment variables must be simple variables whose values are strings, and they often have names consisting of upper-case letters.
The use of environment variables is to keep track of data in the current shell session, but also to allow any started process to take part of that data. The typical case of this is the
PATH environment variable, which may be set in the shell and later used by any program that wants to start programs without specifying a full path to them.
The collection of environment variables in a process is often referred to as "the environment of the process". Each process has its own environment.
Environment variables can only be "forwarded", i.e. a child process can never change the environment variables in its parent process, and other than setting up the environment for a child process upon starting it, a parent process may not change the existing environment of a child process.
Environment variables may be listed with
env (without any arguments). Other than that, they appear the same as non-exported shell variables in a shell session. This is a bit special for the shell as most other programming languages don't usually intermix "ordinary" variables with environment variables (see below).
env may also be used to set the values of one or several environment variables in the environment of a process without setting them in the current session:
env CC=clang CXX=clang++ make
make with the environment variable
CC set to the value
CXX set to
It may also be used to clear the environment for a process:
env -i bash
bash but does not transfer the current environment to the new
bash process (it will still have environment variables as it creates new ones from its shell initialization scripts).
Example of difference
$ var="hello" # create shell variable "var"
$ bash # start _new_ bash session
$ echo "$var" # no output
$ exit # back to original shell session
$ echo "$var" # "hello" is outputted
$ unset var # remove variable
$ export VAR="hello" # create environment variable "VAR"
$ echo "$VAR" # "hello" is outputted since it's exported
$ exit # back to original shell session
$ unset VAR # remove variable
$ ( export VAR="hello"; echo "$VAR" ) # set env. var "VAR" to "hello" in subshell and echo it
$ echo "$VAR" # no output since a subshell has its own environment
There are library functions in most programming languages that allows for getting and setting the environment variables. Note that since environment variables are stored as a simple key-value relationship, they are not usually "variables" of the language. A program may fetch the value (which is always a character string) corresponding to a key (the name of the environment variable), but will then have to convert it to an integer or whatever data type the language expects the value to have.
In C, environment variables may be accessed using
unsetenv(). Variables created with these routines are inherited in the same way by any process that the C program starts.
Other languages may have special data structures for accomplishing the same thing, like the
%ENV hash in Perl, or the
ENVIRON associative array in most implementations of