Setting environment variable for one program call in bash using env
I think what happens is similar to this situation in which I was also puzzled.
In a nutshell, the variable expansion in the first case is done by the current shell which doesn't have $HELLO
in its environment. In the second case, though, single quotes prevent the current shell from doing the variable expansion, so everything works as expected.
Note how changing single quotes to double quotes prevents this command from working the way you want:
HELLO='Hello World' bash -c "echo $HELLO"
Now this will be failing for the same reason as the first command in your question.
This works and is good for me
$ MY_VAR='Hello' ANOTHER_VAR='World!!!' && echo "$MY_VAR $ANOTHER_VAR"
Hello World!!!
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 noHELLO
variable set in the current shell) - The
env
command will run and set theHELLO='Hello World'
in its environment env
will runecho
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 toHello 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.