How Does eval Work?
Part of the problem with eval is that most of us don't have a clear picture of how it works.
In a nutshell, eval turns a string into a command and executes the command returning the result in place of the command…
$ A=1; B='$A'; echo $B $A $ A=1; B='$A'; eval echo $B 1
Here the single-quotes around ($A) make it a literal instead of a variable so that $B contains ($A) instead of (1). The second pass then executes (echo $A) which yields 1. Using (set -vx), we can see what's happening under the covers…
$ set -vx; A=1; B='$A'; eval echo $B + set -vx + A=1 + B='$A' + eval echo '$A' echo $A ++ echo 1 1
Taking it line by line...
Fire off our "program"…
$ set -vx; A=1; B='$A'; eval echo $B
Show each line and all expansions
+ set -vx
Set variable A to 1
+ A=1
Set variable B to the literal string '$A'
+ B='$A'
Replace B with '$A'
+ eval echo '$A'
Execute
echo $A
Replace (eval echo '$A') with (echo 1) and execute it
++ echo 1
Show the result
1
The easy way to get the quoting right
One problem when trying to write an eval command is to get the quoting right, what is expanded, when etc…It turns out that it's in fact pretty easy when you realize that the result of the first expansion should be bash code just like the one you would put in your script. Let's take an example:
var=value name=var eval echo "$name has a value of \"$\$name\"" #wrong!
To correct this, the trick is simply to replace eval with echo. What echo prints should look just like what you would write in a script.
$ echo echo "$name has a value of \"$\$name\"" echo var has a value of "$$name" #hmm 2 $ and name has not been expanded so too many quotes $ echo echo "$name has a value of \"$$name\"" echo var has a value of "3090name" # $$ is expanded to the pid of the shell $ echo echo "$name has a value of \"\$$name\"" echo var has a value of "$var" # now that looks good. let's replace with eval $ eval echo "$name has a value of \"\$$name\"" var has a value of value #victory
References
- Advanced Techniques - Using the eval Builtin for Data Structures, Arrays, and Indirection
- eval is Evil (Most languages have an eval command. These are well know posts on the pros and cons)
- Lippert blog posts about Microsoft JScript
Notes
- (-) Performance
- eval runs the language interpreter on the eval'd text so this is an additional pass thru interpreter
- (-) Security
- If any part of the eval'd text comes from outside the program, language constructs can be introduced into it that do malicious and other unwanted thimgs.