Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

If I run

export TEST=foo
echo $TEST

It outputs foo.

If I run

TEST=foo echo $TEST

It does not. How can I get this functionality without using export or a script?

share|improve this question
up vote 59 down vote accepted

This is because the shell expands the variable in the command line before it actually runs the command and at that time the variable doesn't exist. If you use

TEST=foo; echo $TEST

it will work.

export will make the variable appear in the environment of subsequently executed commands (for on how this works in bash see help export). If you only need the variable to appear in the environment of one command, use what you have tried, i.e.:

TEST=foo your-application
share|improve this answer
What about /usr/bin/env? that doesn't work either, do you know why? – Benubird Jul 9 '14 at 16:43
The same reason - the shell expands the $TEST before the command line is executed. Once the echo is running (also note that echo will usually translate to the shell built-in command and not to /bin/echo) it sees the variable set in its environment. However, echo $TEST doesn't tell echo to output the contents of variable TEST from its environment. It tells the shell to run echo with argument being whatever currently is in the variable called TEST - and those are two very different things. – peterph Jul 9 '14 at 17:41

I suspect you want to have shell variables to have a limited scope, rather than environment variables. Environment variables are a list of strings passed to commands when they are executed.


var=value echo whatever

You're passing the var=value string to the environment that echo receives. However, echo doesn't do anything with its environment list and anyway in most shells, echo is built in and therefore not executed.

If you had written

var=value sh -c 'echo "$var"'

That would have been another matter. Here, we're passing var=value to the sh command, and sh does happen to use its environment. Shells convert each of the variables they receive from their environment to a shell variable, so the var environment variable sh receives will be converted to a $var variable, and when it expands it in that echo command line, that will become echo value. Because the environment is by default inherited, echo will also receive var=value in its environment (or would if it were executed), but again, echo doesn't care about the environment.

Now, if as I suspect, what you want is to limit the scope of shell variables, there are several possible approaches.

Portably (Bourne and POSIX):

(var=value; echo "1: $var"); echo "2: $var2

The (...) above starts a sub-shell (a new shell process), so any variable declared there will only affect that sub-shell, so I'd expect the code above to output "1: value" and "2: " or "2: whatever-var-was-set-to-before".

Linuxly (specified by the LSB and Debian policy, so supported by the sh of virtually every non-embedded Linux), you can use functions and the "local" builtin:

f() {
  local var
  echo "1: $var"
echo "2: $var"

With zsh, you can use inline functions:

(){ local var=value; echo "1: $var"; }; echo "2: $var"


function { local var=value; echo "1: $var"; }; echo "2: $var"

With bash and zsh (but not ash, pdksh or AT&T ksh), this trick also works:

var=value eval 'echo "1: $var"'; echo "2: $var"
share|improve this answer

You can get this working by using:

TEST=foo && echo $TEST
share|improve this answer

Your Answer


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.