Bash Variables – Difference Between Exported and Non-Exported Shell Variables

environment-variablesshell

Bash seems to differentiate between variables which have been exported and those which have not.

example:

$ FOO=BAR
$ env | grep FOO
$ set | grep FOO
FOO=BAR

set sees the variable but env does not.

$ export BAR=FOO
$ env | grep FOO
BAR=FOO
$ set | grep FOO
BAR=FOO
FOO=BAR

set sees both variables but env sees only the exported variable.

I know that set is a bash builtin and env is not.

What are the differences between variables which are exported and those which are not?

Best Answer

Exported variables are carried into the environment of commands executed by the shell that exported them, while non-exported variables are local to the current shell invocation. From the export man page:

The shell shall give the export attribute to the variables corresponding to the specified names, which shall cause them to be in the environment of subsequently executed commands.

set outputs the current environment, which includes any local non-exported variables. env is used to launch programs in a new environment, and with no arguments will output what that new environment would be. Since env is creating a new environment, only exported variables are brought through, as is the case for any program launched from that shell. For example, spawning a second shell within the first (I used $$ to represent prompts in the inner shell):

$ FOO=BAR
$ bash
$$ echo $FOO             # Note the empty line

$$ exit
$ export FOO
$ bash
$$ echo $FOO
BAR
$$

Note that it's the variable that's exported, not just its value. This means that once you export FOO, FOO becomes a global variable and shows up in subsequent environments, even if changed later:

$ export FOO
$ FOO=BAR
$ bash
$$ echo $FOO
BAR
$$
Related Question