Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top
> echo "hi"
> VAR='echo "hi"'
> $VAR

Why is the output of the above commands different?

A similar thing occurs with single quotes:

> VAR="echo 'hi'"
> $VAR
> 'hi'
share|improve this question
Please do not get in the habit of embedding executable script snippets in variables. This tends to be tricky at best and eval is a minefield of potential security holes which you must tread very carefully – jw013 May 11 '12 at 17:15
@jw013 Good point and great articles. I like the quote "Variables hold data, functions hold code." from the first link, but for my usage, the data that is given to a function (in this case, at) is code. Any tips on a safer way to organize/collect code that will be given to at? – Cory Klein May 11 '12 at 17:38
at takes sh syntax as input. Thus generating input for at means generating valid, properly quoted sh syntax from arbitrary input, which is not trivial, so I'd try to avoid it if at all possible. It would really help if you could give a little more detail on what you are trying to accomplish. – jw013 May 11 '12 at 17:56
Sorry, I didn't want to distract with too much detail, but what I'm doing isn't really complicated, IMO. I'm creating a script that takes a "time" and a "message". It then runs at for the given "time", and tells at to run the command dzen2. dzen2 takes the "message" from stdin, and also uses some other static parameters. The difficulty is that I need to pipe the "message" parameter from the user into the dzen2 command, but I'm not actually running dzen2 myself, I'm telling at to do it. – Cory Klein May 11 '12 at 18:02
@jw013 I ended up getting everything to work just fine, by the way. – Cory Klein May 11 '12 at 18:33
up vote 11 down vote accepted

The extra pair of quotes would be consumed only by an extra evaluation step. For example forced by eval:

bash-4.2$ VAR='echo "hi"'

bash-4.2$ $VAR

bash-4.2$ eval $VAR

But generally is a bad idea to put commands with parameters in one string. Use an array instead:

bash-4.2$ VAR=(echo "hi")

bash-4.2$ "${VAR[@]}"
share|improve this answer
It's also important to note that quotes are evaluated differently; double quotes (") allow evaluation of the enclosed string, single quotes (') print the string as a literal. Example: "$(ls)" and '$(ls)'. This is the reason why quotes appear in original questions examples. – Joseph Kern May 12 '12 at 17:00
An array is also a source of problems. Code belongs to functions, data to variables. The example you present works only because the quotes are removed in the split of the array. A printf '<%s> ' "${VAR[@]}" will show that quotes have been removed already. If you set VAR as VAR=(echo \"hi\") to actually have quotes, the same problem appears again, $ ${VAR[@]} will print "hi" – BinaryZebra Jan 17 at 6:10

Quote removal only occurs on the original input words, not on the result of expansions. Quotes that are part of expanded variables are untouched.

share|improve this answer

If you step back a bit, you can see why variable substitution absolutely should retain quotes.

The point of quotes in a Unix/Linux/BSD shell is to keep pieces of a string together that would otherwise get parsed as multiple strings. Since by default a shell uses whitespace as a token separator, a string with spaces (like "one two three") if not quoted or escaped somehow, would get parsed as 3 strings: "one", "two" and "three".

If a programmer wants a string with the value of some variable interpolated:

STRING="one $VAR three"

the shell should absolutely not remove the quotes: the string containing spaces would get parsed as 3 smaller strings.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.