
The textbook says in bash scripting, eval plays a role that the expression comes after will be evaluated twice before the final execution. By saying evaluation, it means the variables begining with $ will be translated to whatever its value is.
Let’s see some examples.
1 | $ a='10' |
Now b is assigned with a, and this a is simply a string, not a variable yet.
1 | $ echo $a |
Now we execute these two variables in different ways:
1 | $ $a |
1 | $ $b |
But if we now evaluate \$$b, as we know \ will escape the $ sign, something interesting will show up.
1 | # experiment 1 |
Some conclusions may be drawn from the above experiments:
Before each execution of command, the known variables in the expression will be converted to its value. As in experiment 1,
\$$bis translated to$abefore executing, then$ais executed as if it is a command, and apparently results in a not-found error. Another example would be1
2$ eval echo \$$b
10With
eval, the entire expression will be evaluated twice.\$$bis translated to$ain the first place, thenecho $ais executed. Similarly,$ais translated to10before this execution, and10is printed on screen as a result.There is difference between experiment 1 and 4 is because that
\$$bis actually executing$aas a command, whileeval \$$bwill first convert $b into a, then evaluates again from$ato10. Now10is executed as a command.` `and$()are called “command substitution”, which means the expression within will be evaluated and executed before the outside command gets in. The outside command usually isecho.- It is said that
` `and$()should be interchangeable, however it apparently is not, judging from experiment 2 and 3. - From experiment 2 and 3, we could see that
$(\$$b)seems to have been successfully translated\$$binto$a. But`\$$b`seems to have first converted\$$into$$, which is the process ID of the current shell, then concatenated ‘b’ at the end and return. - Therefore a good guess is that
` `grants higher priority to escaped characters than variables when evaluating. - It is recommended to use
$()instead of` `for command substitution.
- It is said that
Consider another example of using
evaland$():1
2
3
4
5
6$ eval echo \$$b
10
$ eval $(echo \$$b)
command not found: 10
$ $(echo \$$b)
command not found: $aeval echo \$$bevaluated\$$bto$a, then evaluated$ato its value10before echoing it out, finally echoed the result.eval $(echo \$$b)did the first three steps the same as above, but it has one more step, which was what$()did, to execute the result. Therefore you got a not-found error message.$(echo \$$b)did the same as the second example, except the double evaluation part. That is, first evaluate\$$bto$a, which is associated with “echo”; then echoed it out as a string “$a”; lastly, ran it as a command, and received a not-found error said “command ‘$a’ was not found”.