The 'eval' mechanism
Suppose you are using variables that contain values representing
the names of other variables. For instance, you wish to check the
values of variables X1 through X100 , and
you need a loop to perform this task. You cannot choose another
variable N , loop the value of N from
1 to 100 using expr , and
examine the value of X$N . It simply won't work. Nor
does the shell allow indexed variables, such as arrays as
in Pascal or C. You must use eval instead;
eval will examine its arguments, and concatenate them
to form a command it then executes. The arguments to
eval are examined and any environment variables are
replaced by their values. This forms the command that is then
executed. So to print out the values of PS1 ,
PS2 and HOME , we might have:
for i in HOME PS1 PS2
do
eval echo The value of $i is '$'$i
done
For the first iteration of the loop, the value of i
is HOME ; the command
eval echo The value of $i is '$'$i
is then executed. The first thing that eval does is
to replace $i i by HOME and remove the
quotes, and then the remainder of the line after eval
is executed as a command itself:
echo The value of HOME is $HOME
This process is then repeated with i set to
PS1 and then to PS2 .
Worked example
Create a script to read in a single-line command and execute
it.
Solution: Use read to read in the
command into a variable (say CMD ) and
eval to execute that command.
echo "Type a command:" # Prompt the user ...
read CMD # read in the command ...
eval $CMD # and run it
Note that the last line of the script must not be simply
$CMD - see what happens if you change that line to
$CMD and then enter ls $HOME as the
command. You will get a message
ls: $HOME: No such file or directory
indicating that it was trying to find a file whose actual name
is $HOME .
If you find yourself needing to specify an array of variables
while shell programming, then using eval is the only
method available to you. Your problem is likely to be solved more
effectively using another utility, and Awk is recommended.
|