One secret is to stop thinking of quotes as enclosures, and more like toggle switches. They turn shell interpretation of characters on and off.* The only difference between single and double quotes is that double quotes continue to allow interpretation of a few characters, specifically "
$,
`,
\", which allows parameter expansion and backslash escaping to continue happen. See the QUOTING section of the bash manpage for more details on how various characters are treated.
Another thing to understand is that pretty much
everything the shell does, including quoting, only has one final purpose -- to create a list of arguments (tokens) for the command being run. Syntactical quotes are actually among the first things processed, and are
removed from the line. Only if a quote mark is escaped by another quote or backslash will it become part of the argument itself. But the vast majority of commands do not accept literal quotes anyway.
http://mywiki.wooledge.org/Arguments
http://mywiki.wooledge.org/WordSplitting
http://mywiki.wooledge.org/Quotes
http://mywiki.wooledge.org/BashParser
As for this:
Code:
gcc -g2 -O2 -DVERSION='"123"' ...
The first single quote toggles interpretation off, so everything up to the next single quote, including the two double-quotes, are treated as literal characters. The single quotes themselves are removed from the line. So after processing by the shell,
gcc gets launched with the literal string:
...including the quotes. Now, does
gcc need it to look like this, or not? I really don't know, as my experience with it is limited. But I imagine that it doesn't, so in this case you probably don't need any quote marks at all.
-----
*Note that there are certain situations where nested containers create separate interpretation contexts. i.e.:
Code:
echo "A nested command: $( cat "filename with spaces.txt" )."
echo "A parameter substitution (left hand side): ${var/'string$with`special|characters*'/replacement string}"
The internal sets of quotes are treated separately from the outer ones, but they still act as toggles inside their respective parsing environments.