Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

strange behavior of 'echo' in 'env' bash

When I am trying echo variable inside 'env' command I got nothing, but I can see it using 'printenv' command:

root@devel:~# env xxx=23 echo $xxx

root@devel:~# env xxx=23 printenv | grep xxx
xxx=23

what's wrong here?

like image 428
urusai_na Avatar asked Dec 10 '17 08:12

urusai_na


2 Answers

env xxx=23 echo $xxx

In the above, the shell evaluates $xxx before env is executed. Thus, nothing is echoed.

In more detail, the shell sees the four words env, xxx=23, echo and $xxx. It interprets env as a command name and xxx=23, echo, and $xxx as three arguments which will be passed to the command env. It evaluates $xxx before passing it to the command env.

By contrast, in the following, there are no shell variables for the shell to evaluate. Instead env is executed with two arguments, xxx=23 and printenv. env sets the environment variable xxx and then executes printenv:

$ env xxx=23 printenv | grep xxx
xxx=23

Similarly, observe:

$ env xxx=23 sh -c 'echo $xxx'
23

Since $xxx is inside single-quotes, the shell does not evaluate it. Instead is runs env with four arguments: xxx=23, sh, -c, and echo $xxx. After env sets environment variable xxx, it executes sh with arguments -c and echo $xxx. The $xxx is evaluated when sh is executed and hence it sees the variable xxx.

like image 183
John1024 Avatar answered Oct 11 '22 10:10

John1024


When you run env xxx=23 echo $xxx, the variable xxx=23 becomes visible to the echo process during its execution. But in echo $xxx the value of $xxx is not evaluated by echo, it is evaluated by the currently executing shell. And since the env ... invocation doesn't affect the current shell, the value of $xxx is whatever it was before you executed this command (probably unset).

echo is not a good way to test the effect of env, because you cannot make the echo command print a specific value defined in its environment. Your example with printenv is better, because it dumps the content of environment variables it knows about. Another good test is what @john wrote in his answer, invoking another shell and make the shell print a chosen environment variable. Any program with the ability to print the content of environment variables would work.

like image 45
janos Avatar answered Oct 11 '22 10:10

janos