Question

x="a=b"
`echo $x`
echo $a

I expect the second line to generate "a=b", and execute it in the context of the main shell, resulting in a new variable a with value b. However, what I really get (if I enter the commands manually) is the error message after the second line, bash: a=b: command not found

Why is that so?

Was it helpful?

Solution

It's because of the order in which bash parses the command line. It looks for variable definitions (e.g. a=b) before performing variable and command substitution (e.g. commands in backticks). Because of this, by the time echo $x is replaced by a=b, it's too late for bash to see this as a variable definition and it's parsed as a command instead. The same thing would've happened if you'd just used $x as the command (instead of echo in backticks). As in @mvds's answer, the eval command can be used to force the command to be reparsed from the beginning, meaning that it'll be recognized as a variable definition:

$ x="a=b"
$ `echo $x`
-bash: a=b: command not found
$ $(echo $x)  # Exact same thing, but with cleaner syntax
-bash: a=b: command not found
$ $x  # This also does the same thing, but without some extra steps
-bash: a=b: command not found
$ eval "$x"  # This will actually work
$ echo $a
b
$ a=  # Start over
$ eval "$(echo "$x")"  # Another way of doing the same thing, with extra steps
$ echo $a
b

Note that when using eval I've put all of the references to $x in double-quotes -- this is to prevent the later phases of bash parsing (e.g. word splitting) from happening twice, since bash will finish its regular parsing process, then recognize the eval command, and then redo the entire parsing process again. It's really easy to get unexpected results from using eval, and this removes at least some of the potential for trouble.

OTHER TIPS

Try

eval $x

(And we need 30 characters for this answer to be posted)

What your first echo line does is running in a subshell and returns its value to the callee.. The same result is achieved using $() and is - by the way - easier to use than backticks.

So, what you are doing is first running echo $x (which returns a=b). And, because of the backticks, a=b is returned to the shell that tries to run that line as a command which - obviously - won't work.

Try this in a shell:

$(echo ls)

And you will clearly see what is happening.

Did you try $x in that funny apostrophes? Without echo, echo seems to be only for displaying string, not execute commands.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top