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
$$