Reputation: 1360
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?
Upvotes: 63
Views: 51345
Reputation: 39253
Here is an easier way to confirm shell is working as expected.
env A=42 env
env
The first command sets A
to 42 and runs env
. The second command also runs env
. Compare the output of both.
Upvotes: 2
Reputation: 473
As nos noted, expansion of your variable passed to echo
occurs before that variable gets set.
One alternative not yet mentioned in the earlier answers is to use:
$ a=abc eval 'echo $a'
abc
$ echo $a
<blank>
Note that you have to use the a=abc cmd
syntax and not env a=abc cmd
syntax; apparently env
doesn't play nice with the built-in eval
.
Upvotes: 2
Reputation: 229098
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:
$HELLO
'HELLO=Hello World'
, 'echo'
and ''
(an empty string, since there's no HELLO
variable set in the current shell)env
command will run and set the HELLO='Hello World'
in its environmentenv
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:
HELLO='Hello World
for the following command'-c'
and 'echo $HELLO'
echo $HELLO
$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.echo 'Hello World'
If you tried to do e.g. this:
env HELLO='Hello World' echo '$HELLO'
$HELLO
is enclosed in single quotes'HELLO=Hello World'
, 'echo'
and '$HELLO'
HELLO='Hello World'
in its environment'$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.
Upvotes: 100
Reputation: 4448
This works and is good for me
$ MY_VAR='Hello' ANOTHER_VAR='World!!!' && echo "$MY_VAR $ANOTHER_VAR"
Hello World!!!
Upvotes: 3
Reputation: 65791
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.
Upvotes: 5