Setting environment variable for one program call in bash using env

Niklas picture Niklas · Dec 21, 2012 · Viewed 27.4k times · Source

I am trying to invoke a shell command with a modified environment via the command env.

According to the manual

env HELLO='Hello World' echo $HELLO

should echo Hello World, but it doesn't. If I do

HELLO='Hello World' bash -c 'echo $HELLO'

it prints Hello World as expected (thanks to this answer for this info).

What am I missing here?

Cheers, Niklas

Answer

nos picture nos · Dec 21, 2012

It's because in your first case, your current shell expands the $HELLO variable before running the commands. And there's no HELLO variable set in your current shell.

env HELLO='Hello World' echo $HELLO

will do this:

  • expand any variables given, in this case $HELLO
  • run env with the 3 arguments 'HELLO=Hello World', 'echo' and '' (an empty string, since there's no HELLO variable set in the current shell)
  • The env command will run and set the HELLO='Hello World' in its environment
  • env will run echo with the argument '' (an empty string)

As you see, the current shell expanded the $HELLO variable, which isn't set.

HELLO='Hello World' bash -c 'echo $HELLO'

will do this:

  • set the variable HELLO='Hello World for the following command
  • run bash with the 2 arguments '-c' and 'echo $HELLO'
  • since the last argument is enclosed in single quotes, nothing inside it is expanded
  • the new bash in turn will run the command echo $HELLO
  • To run echo $HELLO in the new bash sub-shell, bash first expands anything it can, $HELLO in this case, and the parent shell set that to Hello World for us.
  • The subshell runs echo 'Hello World'

If you tried to do e.g. this:

env HELLO='Hello World' echo '$HELLO'
  • The current shell would expand anything it can, which is nothing since $HELLO is enclosed in single quotes
  • run env with the 3 arguments 'HELLO=Hello World', 'echo' and '$HELLO'
  • The env command will run and set the HELLO='Hello World' in its environment
  • env will run echo with the argument '$HELLO'

In this case, there's no shell that will expand the $HELLO, so echo receives the string $HELLO and prints out that. Variable expansion is done by shells only.