The short answer is, you cannot put quotes in quotes that way directly, the shell won't do that kind of doublethink. You asked for literal quotes, so it gave you literal quotes; making them go away takes an eval, which means big trouble. If someone manages to cram `rm -RF ~/ into your string, eval will execute that!
This lets you do splitting on arguments instead of spaces, preserving your strings literally without having to deal with quotes inside quotes. This avoids the eval, and makes your code much safer.
Very true! The shell maintains literally a switch, which flips between "inside quotes" and "outside quotes". Once it encounters a quotation mark, the switch flips into the other position. Per default it is on "outside a quotation". If the shell encounters the first quotation mark the switch flips into "inside quotes" and everything is interpreted accordingly, once it encounters the second quote the switch flips back to "outside quotes" again.
Because the command is being run from a variable. I'm guessing he didn't do that on a lark, but because he wanted the contents to vary depending on how the script is used.
That leaves room for injection of malicious strings unless done very, very carefully.
It's also completely avoidable by just not using eval at all.
Let's try to be mor specific. It's interesting, I'm curious about it.
The only way I'm able to think of is that of a parameter automatically built reading things (maliciously writable by others). For example, let's say I want to discard all files having the same extension of the files in the current directory.
lem@biggy:/tmp/dir$ ls -a1
.
..
a.txt
b.sh
c.pdf
malicious.; ls ~
lem@biggy:/tmp/dir$ for a in *.* ; do arr+=( "-not -name \*.${a##*.}" ) ; done
How about a file named `rm -Rf ~/` ? That's a perfectly valid filename. Feed that filename into an eval and it will be executed.
If you quote it defensively, so what? They can put quotes and spaces in the filename to unquote it.
It needn't even be malicious. People can generate weird filenames by accident sometimes, and anything resembling shell syntax is something eval will try to parse, potentially causing syntax errors or worse. Eval can parse any shell syntax, so the only limit is your imagination.
And it's completely avoidable. Eval is not needed here.