Using eval
is often discouraged because it allows execution of arbitrary code. However, if we use eval echo
, then it looks like the rest of the string will become arguments of echo
so it should be safe. Am I correct on this?
4 Answers
Counterexample:
DANGEROUS=">foo"
eval echo $DANGEROUS
The arbitrary arguments to echo
could have done something more nefarious than creating a file called "foo".

- 44,132
-
6Also:
DANGEROUS="hello;ls"
, for arbitrary commands in place ofls
. – Kusalananda Dec 24 '16 at 22:18 -
2
-
Would
eval echo '"'"$DANGEROUS"'"'
work? It seems to on https://goo.gl/L2pPQP – Ismael Miguel Dec 26 '16 at 15:25 -
@IsmaelMiguel That doesn't work for wizzwizz, Cyker, or sorontar's examples, or for anything with double-quotes in the string (e.g.
DANGEROUS='">foo"'
). – Gordon Davisson Dec 26 '16 at 18:33 -
-
Or
DANGEROUS='whatever; reboot'
. IOW, the content of $DANGEROUS doesn't necessarily become arguments toecho
. – Stéphane Chazelas Jan 05 '18 at 09:45 -
Even that would be bad if
foo
already existed and (for some reason) had something important in it that couldn't be easily replaced. – Sparkette Apr 19 '18 at 15:32
@Celada has provided an excellent answer. To demonstrate eval
is really evil, here's something more nefarious than creating a file called "foo":
DANGEROUS='$(rm foo)'
eval echo "$DANGEROUS"
And of course there can be something more nefarious than something more nefarious than creating a file called "foo".

- 4,274
- 7
- 36
- 46
-
9+1 for demonstrating that quoting the variable like
"$THIS"
instead of just having it like$THIS
doesn't even help! – Celada Dec 24 '16 at 22:34 -
Sending an aditional pair of quotes seems to help. Something like
eval echo '"'"$DANGEROUS"'"'
. Try it on https://goo.gl/L2pPQP – Ismael Miguel Dec 26 '16 at 15:25 -
Actually, your example isn't any more nefarious than
>foo
, because "creating a file called 'foo'" isn't necessarily all that>foo
does. The only real difference your example has is that it doesn't leave an empty file behind. The contents are still gone. – Sparkette Apr 19 '18 at 15:35
No, it is not always safe. An eval could execute any command.
A safe command, like this (the date is not executed as it is inside single quotes):
$ echo '$(date)'
$(date)
Becomes dangerous if used with eval:
$ eval echo '$(date)'
Sat Dec 24 22:55:55 UTC 2016
Of course, date could be any command.
One way to improve this is to additionally quote the arguments to eval:
$ eval echo '\$(date)'
$(date)
But it is usually difficult to correctly quote twice an expression.
And it becomes impossible to control the correct quoting if the expression could be set by an external attacker, like:
$ var='$(date);echo Hello!'
$ eval echo "$var"
Sat Dec 24 23:01:48 UTC 2016
Hello!
While it is true that eval
always needs to be approached with caution, the eval echo
construction is not always pointless and can be used safely. I recently needed it to get multiple brace expansions evaluated in the order I needed them done.
bash
does multiple brace expansions from left to right, so
xargs -I_ cat _/{11..15}/{8..5}.jpg
expands to
xargs -I_ cat _/11/8.jpg _/11/7.jpg _/11/6.jpg _/11/5.jpg _/12/8.jpg _/12/7.jpg _/12/6.jpg _/12/5.jpg _/13/8.jpg _/13/7.jpg _/13/6.jpg _/13/5.jpg _/14/8.jpg _/14/7.jpg _/14/6.jpg _/14/5.jpg _/15/8.jpg _/15/7.jpg _/15/6.jpg _/15/5.jpg
but I needed the second brace expansion done first, yielding
xargs -I_ cat _/11/8.jpg _/12/8.jpg _/13/8.jpg _/14/8.jpg _/15/8.jpg _/11/7.jpg _/12/7.jpg _/13/7.jpg _/14/7.jpg _/15/7.jpg _/11/6.jpg _/12/6.jpg _/13/6.jpg _/14/6.jpg _/15/6.jpg _/11/5.jpg _/12/5.jpg _/13/5.jpg _/14/5.jpg _/15/5.jpg
The best I could come up with to do that was
xargs -I_ cat $(eval echo _/'{11..15}'/{8..5}.jpg)
This works because the single quotes protect the first set of braces from expansion during the parsing of the eval
command line, leaving them to be expanded by the subshell invoked by eval
.
There may be some cunning scheme involving nested brace expansions that allows this to happen in one step, but if there is I'm too old and stupid to see it. There are also shells other than bash
that allow for tidier ways of achieving this kind of thing. But in any case, this use of eval
is safe because its arguments are all fixed strings that contain no parameter expansions.

- 314
-
You don't need echo and the command substitution here (which also has a dependency on $IFS). You could do
eval xargs -I_ cat _/'{11..15}'/{8..5}.jpg
– Stéphane Chazelas Jan 05 '18 at 10:51 -
That works too, but it makes the subshell process spawned by eval stick around until the xargs process is finished; the eval echo version makes that subshell go away before xargs is even started. This is probably only important to others who are as anal as me about what shows up in htop tree views and set -x logs though :-) – flabdablet Jan 05 '18 at 16:40
-n
, you can just do it with an unquoted variable likeecho $arguments
or if$arguments
is an arrayecho "${arguments[@]}"
. Usingeval echo
is pointless even if it were safe. – JoL Dec 25 '16 at 23:03