Command
eval
is builtin shell builtin, part of POSIX. In practice, eval takes a string as argument and evaluates that string as if you would typed it if it was command written in the bash script. This can still sound unclear, but important point is that you can basically generate bash commands, using eval.
We can write function like this
1 2 3 4 |
leave_message_at(){ eval "$1=HelloWorld"; echo "$1"; } |
And then we can use this code as follows
1 2 |
leave_message_at "MAILBOX123" echo "$MAILBOX123" |
On the standard output we can see printed HelloWorld
. The leave_message_at
function takes 1 argument, which specifies where the message should be stored, and its the builtineval
which does the work.
Evaluation process
Here is what is happens during evaluation of command eval "$1=HelloWorld"
;
- leave_message_at is invoked with 1 argument, referred to as
$1
, with valueMAILBOX123
- Bash variable expansion is applied on the string
$1=HelloWorld
. The string$1
is expanded to its value, resulting in stringMAILBOX123=HelloWorld
- Now, the string
MAILBOX123=HelloWorld
is passed to eval as first argument. And as I mentioned before, eval will simply evaluate this string as a command typed in bash.
Be careful with escaping characters in string you are passing to eval, if you don’t want them to be expanded in first round of evaluation.
How can we use eval in practice? It’s very generic, so usecases are unlimited. However, here is something for inspiration.
Run command stored in a variable
In case that, for whatever reason, you have variable which contains a command you want to run, you can do that with eval.
1 2 |
MY_CMD='for i in `seq 1 10`; do printf "$i "; done; echo ""' eval $MY_CMD |
Which prints out 1 2 3 4 5 6 7 8 9 10
as the result.
Return string value from a function
Unlike in other languages, there is no standard way to return a string value from bash function. People more ways how to approach this problem, and one of the solutions can looks like this
1 2 3 4 5 6 7 8 9 |
#!/bin/bash receive_message(){ eval "$1=Lovely message returned from a function" echo "$1" } receive_message "MESSAGE" echo "$MESSAGE" |
which prints Lovely message returned from a function
as a result.