- Article pages now have a discussion option at the bottom (moderated/captcha, but no registration needed)

This is an old revision of the document!


The eval builtin command

Synopsis

eval: eval [arg ...]

Description

This page doesn't yet contain the obligatory "just don't use eval" speech. See the links at the bottom if you don't know what you're doing, or help to improve this article if you do.

eval takes its arguments, concatenates them, and executes the resulting string as Bash code in the current execution environment. eval in Bash works in essentially the same way as most other languages that have an eval function. Perhaps the easiest way to think about eval is that it works in the same way as running bash -c 'bash code…' from a script, except in the case of eval, the given code is executed in the current shell environment rather than a child process.

Examples

In this example, the literal text within the here-document is executed as Bash code exactly as though it were to appear within the script in place of the eval command below it.

#!/usr/bin/env bash
{ printf -v shellcode %s "$(</dev/stdin)"; } <<"EOF"
... arbitrary bash code here ...
EOF

eval "$shellcode"

Frequently, eval is used to cause side-effects by performing a pass of expansion on the code before executing the resulting string. This allows for things that otherwise wouldn't be possible with ordinary Bash syntax. This also, of course, makes eval the most powerful command in all of shell programming (and in most other languages for that matter).

This code defines a set of identical functions using the supplied names. eval is the only way to achieve this effect.

main() {
    local fun='() { echo "$FUNCNAME"; }' x

    for x in {f..n}; do
        eval "${x}${fun}"
    done

    "$@"
}

main "$@"

The printf %q format string performs shell escaping on its arguments. This makes printf %q the "anti-eval" - with each pass of a string through printf requiring another eval to peel off the escaping again.

shopt -s lastpipe
: 'echo hi'
for ((n=0;n++<4;)) do
    printf %q "$_" >&$((n<4?1:2)) |
    : "$(</dev/stdin)"
done 2>&1 |
eval eval eval eval eval "$(</dev/stdin)" # eventually prints "hi"

The above example is mostly fun and games but illustrates the printf %q property.

Portability considerations

See also

Discussion

Chris F.A. Johnson, 2012/06/04 00:13

"just don't use eval" is not obligatory; it's just plain wrong!

Yes, care must be taken when using eval, but it's no different from many other commands in that respect.

Jan Schampera, 2012/07/01 13:46

I agree. It should not be damned. Shell newbies should just be really warned. If one knows what he's doing, everything's fine :-)

Dan Douglas, 2012/07/26 04:42

I also agree (I wrote the page and that note). eval isn't as bad as some make it out to be - particularly in a language whose most fundamental principle is: "take a string, parse, evaluate, reparse, evaluate again, repeat until you eventually run a command". Warnings are needed for beginners. It takes some experience to know where eval is appropriate. Blah blah, we all know this.

I would also say that the more featureful of a shell you're using, the more infrequently it's appropriate to use eval.

Enter your comment
 
commands/builtin/eval.1338422519.txt · Last modified: 2012/05/31 02:01 by ormaaj
GNU Free Documentation License 1.3
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0