Take the 2-minute tour ×
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.
> echo "hi"
hi
> VAR='echo "hi"'
> $VAR
"hi"

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
4  
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
show 1 more comment

3 Answers

up vote 8 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
"hi"

bash-4.2$ eval $VAR
hi

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[@]}"
hi
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
add comment

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:

VAR=two
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
add comment

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
add comment

Your Answer

 
discard

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.