Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I read here that the purpose of export in a shell is to make the variable available to sub-processes started from the shell.

However, I have also read here and here that "Processes inherit their environment from their parent (the process which started them)."

If this is the case, why do we need export? What am I missing?

Are shell variables not part of the environment by default? What is the difference?

share|improve this question

3 Answers 3

up vote 22 down vote accepted

Your assumption is that shell variables are in the environment. This is incorrect. The export command is what defines a name to be in the environment at all. Thus:

a=1 b=2
export b

results in the current shell knowing that $a expands to 1 and $b to 2, but subprocesses will not know anything about a because it is not part of the environment (even in the current shell).

Some useful tools:

  • set: Useful for viewing the current shell's parameters, exported-or-not
  • set -k: Sets assigned args in the environment. Consider f() { set -k; env; }; f a=1
  • export: Tells the shell to put a name in the environment. Export and assignment are two entirely different operations.
  • env: As an external command, env can only tell you about the inherited environment, thus, it's useful for sanity checking.
  • env -i: Useful for clearing the environment before starting a subprocess.

Alternatives to export:

  1. name=val command # Assignment before command exports that name to the command.
  2. declare/local -x name # Exports name, particularly useful in shell functions when you want to avoid exposing the name to outside scope.
share|improve this answer

There's a difference between shell variables and environment variables. If you define a shell variable without exporting it, it is not added to the processes environment and thus not inherited to its children.

Using export you tell the shell to add the shell variable to the environment. You can test this using printenv (which just prints its environment to stdout, since it's a child-process you see the effect of exporting variables):

#!/bin/sh

MYVAR="my cool variable"

echo "Without export:"
printenv | grep MYVAR

echo "With export:"
export MYVAR
printenv | grep MYVAR
share|improve this answer

A variable, once exported, is part of the environment. PATH is exported in the shell itself, while custom variables can be exported as needed. Using some setup code:

$ cat subshell.sh 
#!/usr/bin/env bash
declare | grep -e '^PATH=' -e '^foo='

Compare

$ cat test.sh 
#!/usr/bin/env bash
export PATH=/bin
export foo=bar
declare | grep -e '^PATH=' -e '^foo='
./subshell.sh
$ ./test.sh 
PATH=/bin
foo=bar
PATH=/bin
foo=bar

With

$ cat test2.sh 
#!/usr/bin/env bash
PATH=/bin
foo=bar
declare | grep -e '^PATH=' -e '^foo='
./subshell.sh
$ ./test2.sh 
PATH=/bin
foo=bar
PATH=/bin

Since foo is not exported by the shell, and test2.sh never exported it, it was not part of the environment of subshell.sh in the last run.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.