> 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'
> 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'
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
"$(ls)"
and '$(ls)'
. This is the reason why quotes appear in original questions examples.
– Joseph Kern
May 12 '12 at 17:00
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"
–
Jan 17 '16 at 06: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.
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.
eval
is a minefield of potential security holes which you must tread very carefully – jw013 May 11 '12 at 17:15at
) is code. Any tips on a safer way to organize/collect code that will be given toat
? – Cory Klein May 11 '12 at 17:38at
takessh
syntax as input. Thus generating input forat
means generating valid, properly quotedsh
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:56at
for the given "time", and tellsat
to run the commanddzen2
.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 thedzen2
command, but I'm not actually runningdzen2
myself, I'm tellingat
to do it. – Cory Klein May 11 '12 at 18:02