# The eval builtin command ## Synopsis eval: eval [arg ...] ## Description `eval` takes its arguments, concatenates them separated by spaces, 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](../../syntax/redirection.md#here_documents) 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 { myCode=$( ``` - `eval` is another one of the few Bash builtins with keyword-like conditional parsing of arguments that are in the form of compound assignments. ```{=html} ``` $ ( eval a=( a b\\ c d ); printf '<%s> ' "${a[@]}"; echo ) # Only works in Bash. $ ( x=a; eval "$x"=( a b\\ c d ); printf '<%s> ' "${a[@]}"; echo ) # Argument is no longer in the form of a valid assignment, therefore ordinary parsing rules apply. -bash: syntax error near unexpected token `(' $ ( x=a; eval "$x"'=( a b\ c d )'; printf '<%s> ' "${a[@]}"; echo ) # Proper quoting then gives us the expected results. We don't know why Bash does this. Since parentheses are metacharacters, they must ordinary be quoted or escaped when used as arguments. The first example above is the same error as the second in all non-Bash shells, even those with compound assignment. In the case of `eval` it isn't recommended to use this behavior, because unlike e.g. [declare](../../commands/builtin/declare.md), the initial expansion is still subject to all expansions including [word-splitting](../../syntax/expansion/wordsplit.md) and [pathname expansion](../../syntax/expansion/glob.md). $ ( set -x; touch 'x+=(\[[123]\]=*)' 'x+=([3]=yo)'; eval x+=(*); echo "${x[@]}" ) + touch 'x+=(\[[123]\]=*)' 'x+=([3]=yo)' + eval 'x+=(\[[123]\]=*)' 'x+=([3]=yo)' ++ x+=(\[[123]\]=*) ++ x+=([3]=yo) + echo '[[123]]=*' yo [[123]]=* yo Other commands known to be affected by compound assignment arguments include: [let](../../commands/builtin/let.md), [declare](../../commands/builtin/declare.md), [typeset](../../commands/builtin/typeset.md), [local](../../commands/builtin/local.md), [export](../../commands/builtin/export.md), and [readonly](../../commands/builtin/readonly.md). More oddities below show both similarities and differences to commands like [declare](../../commands/builtin/declare.md). The rules for `eval` appear identical to those of [let](../../commands/builtin/let.md). ## See also - [BashFAQ 48 - eval and security issues](http://mywiki.wooledge.org/BashFAQ/048) -- **IMPORTANT** - [Another eval article](http://fvue.nl/wiki/Bash:_Why_use_eval_with_variable_expansion%3F) - [Indirection via eval](http://mywiki.wooledge.org/BashFAQ/006#Assigning_indirect.2BAC8-reference_variables) - [More indirection via eval](http://fvue.nl/wiki/Bash:_Passing_variables_by_reference) - [Martin Väth's \"push\"](https://github.com/vaeth/push) -- `printf %q` work-alike for POSIX. - [The \"magic alias\" hack](http://www.chiark.greenend.org.uk/~sgtatham/aliases.html)