Skip to main content
2 of 11
added 15 characters in body
Stéphane Chazelas
  • 584.6k
  • 96
  • 1.1k
  • 1.7k

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.

In

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 in most shells), 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".

With most Bourne-like shells, you can use functions and the "local" builtin:

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

With zsh, you can use inline functions:

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

or:

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"
Stéphane Chazelas
  • 584.6k
  • 96
  • 1.1k
  • 1.7k