But this will not execute date (or so I thought thanks @Wildcard):.
A correct solution to this command is to sanitize the input, but I will delay talking about this until the second problem of eval has been defined.
SanitizeSanitizing external data.
No matter what an external user place in positional parameter, it will become a number, it may be a big number for which $(( ... )) will fail, but that input will not trigger the execution of any command.
It is now that we can talk about sanitizing variable b from the command above. The command was:
$ b='";date;:"'
$ eval a\=\"\$"$b"\"
Sat Apr 23 01:56:30 UTC 2016
Because b contained several characters that were used to change the line.
$ echo a\=\"\$"$b"\"
a="$";date;:""
Changing to single quotes will not work, some other value of b could match them also. We need to "sanitize" b by removing (at least) the quotes.
We could replace $b by ${b//\"}:
$ eval a\=\"\$"${b//\"}"\"
$ echo "$a"
$;date;:
A more robust variable name sanitizing.
But we can make it even better by acknowledging that a variable name in shell could only have 0-9a-zA_Z and underscores. We can remove all others with this:
$ c="$( LC_COLLATE=C; echo "${b//[^0-9A-Za-z_]}" )"
This will clean the variable b to a valid variable name.
And then, we can add an even more strict check by actually checking that the variable name inside $b (using the cleaned c) exists:
$ if declare -p "$c" &>/dev/null; then eval a\=\"\$"$c"\" ; fi