I’m always confused by bash’s quoting. I hope to put all my quote wisdom in this post and invoke other’s quote wisdom in the comments. I’ll give some examples of what I mean.
Let’s say you have a file with a space: “bla bla.txt”. If I were to ls that file, I would do:
ls 'bla bla.txt'
This works. However, when I want to do this from a variable (in a script) and do:
command="ls 'bla bla.txt'"
$command
The result is:
ls: cannot access 'bla: No such file or directory
ls: cannot access bla.txt': No such file or directory
You can solve this by using eval:
command="ls 'bla bla.txt'"
eval $command
This gives:
bla bla.txt
Some time ago, I suggested this as answer on somebodies question at userfriendly, to which somebody else said that using eval actually makes things worse:
That’s actually worse. . . as the quoting gets re-parsed (remember, ‘eval’ means “take arguments as shell input”), which means that single quotes in the name break it, horribly, and names with spaces get even _worse_.
Another example: let’s say you have two files:
-rw-r----- 1 halfgaar halfgaar 0 2009-10-18 16:51 bla's bla"s.txt
-rw-r----- 1 halfgaar halfgaar 0 2009-10-18 16:52 normal.txt
I’m gonna run this command on it: find . -mindepth 1 -exec ls ‘{}’ \;. When executed without eval, it says this:
find: missing argument to `-exec'
With eval, it says:
./normal.txt
./bla's bla"s.txt
Eval seems to be what I need, so what is wrong with using it? Also, shouldn’t that double quote be a problem? If someone can give a situation where that poses problems, I’m all ears.
Recent Comments