7.2.9. Eval command¶
In the previous section we used the \\
to escape the $
sign
in front of a variable. The last example was:
fruit=apple
echo \$$fruit # gives $apple
This looks like a new variable-value. Can we also access this value ?
% fruit=apple
% apple=jonagold
% echo echo \$$fruit
echo $apple
% echo $(echo \$$fruit)
bash: $apple: command not found
The way it will work is using the shell command eval
. This will take a string
as argument and evaluate this sting as if it was entered from the command line.
The command line we like to run is in this example echo $apple
where the ‘apple’
comes from the expansion of fruit:
% fruit=apple
% apple=jonagold
% eval echo \$$fruit # this expands to "eval echo $apple"
jonagold
% One can also write
echo ${!fruit} # this substitutes the value of the
# variable 'fruit' as variable name between the braces
eval
can be useful to make a variable command. For example, when
you like to include a timestamp with every echo
command:
% date; echo "There is some error"
Wed 26 Jan 2022 07:49:25 PM CET
There is some error
# The problem is that the date is on a seperate line
# we try the following:
% d=$(date); echo "$d: " "There is some error"
Wed 26 Jan 2022 07:51:00 PM CET: There is some error
# Now we want to shortcut this to make it more convenient:
ets='d=$(date); echo "$d: "'
$ets "There is an error"
bash: d=$(date);: command not found
# bash sees the first word (d=$(date);) as a command
# we want to execute the line as it is written on the comandline
# just as it worked before: we use eval
eval $ets "There is an error"
Wed 26 Jan 2022 07:54:47 PM CET: There is an error
# We can also make a shortcut for this:
pts="eval $ets"
$pts "There is an error"
Wed 26 Jan 2022 07:56:44 PM CET: There is an error
# We can define this in the beginning of our script
# and we use $pts instead of echo everywhere. If we
# want to remove the timestamp we can redefine pts
# without changing the script
pts=echo # $pts behave now the same as echo
Note: this can maybe better written by using functions.
Maybe the most used case of eval is when starting ssh-agent
. This
program can keep ssh-keys so that they can be used without asking for
a password every time. The standard way of starting this command is:
eval $(ssh-agent)
The reason is, that ssh-agent
also need to set some environment
variables. It puts this on stdout when starting:
% ssh-agent
SSH_AUTH_SOCK=/tmp/ssh-JQU5mg3DpoIB/agent.28524; export SSH_AUTH_SOCK;
SSH_AGENT_PID=28525; export SSH_AGENT_PID;
echo Agent pid 28525;
Normally, after starting one should manually execute the outputlines. Starting
ssh-agent
with eval
, will start the agent and also ‘eval’ the output
lines.