0

It is often said that variables should be double quoted when used.

In the following example I want to have the command echo "You can't see me" in a variable and run it in such a way that the output is You can't see me. This is the end goal.

$ cmd="echo \"You can't see me\""
$ echo "$cmd"
echo "You can't see me"
$ $cmd
"You can't see me"
$ "$cmd"
echo "You can't see me": command not found

So $cmd ran and it included double quotes which I did not want to have, and following the recommendation of double quoting the variables led to an error.

Does the recommendation have exceptions despite the fact that resources say that they always should be used?

I know how I can get the result that I want by running eval "$cmd" (or without the double quotes), or by an appropriate transformation on the output after running $cmd (without double quotes), but how do I avoid this issue?

Redirect
  • 107

1 Answers1

1

It is often said that ...

the fact that resources say that ...

Do not blindly follow "recommendations"; there's no way to do cargo-cult programming "right". Is there some primary "resource" like the bash(1) manpage or the standard spec that says that?

If you want to eval a string as a script snippet, then you should use eval. That's what it's for:

cmd="echo \"You can't see me\""
eval "$cmd"

When you're using an unquoted variable, its expansions will not be scanned again for shell metacharacters like single or double quotes and reparsed, but will only be split on the characters from the IFS variable and glob-expanded (if it contains any *, ? or [ characters):

cmd="echo \"What's a *? \""

eval "$cmd" What's a *?

$cmd "What's a [all the files in your directory] "

In the last example, cmd will be expanded, then split into echo, "What's, a, *? and ", the *? will be glob expanded, and then echo will be run with all the other strings as arguments, and will print them joined by spaces to stdout (and in some shells, echo will also interpret \n and other escapes in its arguments).