views:

632

answers:

8

Hi all,

I'm sure this question may seem foolish to some of you, but I'm here to learn.
Are these assumptions true for most of the languages ?
EDIT : OK, let's assume I'm talking about Perl/Bash scripting.

'Single quotes'

=> No interpretation at all (e.g. '$' or any metacharacter will be considered as a character and will be printed on screen)

"Double quotes"

=> Variable interpretation

To be more precise about my concerns, I'm writing some shell scripts (in which quotes can sometimes be a big hassle), and wrote this line :

CODIR=`pwd | sed -e "s/$MODNAME//"`

If I had used single quotes in my sed, my pattern would have been '$MODNAME', right ? (and not the actual value of $MODNAME, which is `alpha' in this particular case)

Another problem I had, with an awk inside an echo :

USAGE=`echo -ne "\
Usage : ./\`basename $0\` [-hnvV]\n\
\`ls -l ${MODPATH}/reference/ | awk -F " " '$8 ~ /\w+/{print "> ",$8}'\`"`

I spent some time debugging that one. I came to the conclusion that backticks were escaped so that the interpreter doesn't "split" the command (and stop right before «basename»). In the awk commmand, '$8' is successfully interpreted by awk, thus not by shell. What if I wanted to use a shell variable ? Would I write awk -F "\"$MY_SHELL_VAR\"" ? Because $MY_SHELL_VAR as is, will be interpreted by awk, won't it ?

Don't hesitate to add any information about quoting or backticks !

Thank you ! :)

+4  A: 

Are these assumptions true for most of the languages ?

Answer: No

Henk Holterman
+7  A: 

It varies massively by language. For example, in the C/Java/C++/C# etc family, you can't use single quotes for a string at all - they're only for single characters.

I think it's far better to learn the rules properly for the languages you're actually interested in than to try to generalise.

Jon Skeet
You're absolutely right, I'm so drowned into Perl and Shell that I forgot about my other known languages <_<
Isaac Clarke
+2  A: 

It's definitely not the same for all languages. In Python, for example, single and double quotes are interchangeable. The only difference is that you can include single quotes within a double-quoted string without escaping them and vice versa ("How's it going?").

Also, there are triple-quoted strings that can span multiple lines.

Tim Pietzcker
Interesting, thanks !
Isaac Clarke
+1  A: 

Yes, something like awk -F "\"$MY_SHELL_VAR\"" will work, however in this case you wouldn't be able to use variables in awk, since they will be interpreted by shell, so the way to go is something like this (I will use command simpler than yours, if you don't mind :) ):

awk -F " " '$8 ~ /\w+/{print "> ",$8, '$SOME_SHELL_VAR'}'

Note the single quotes terminating and restarting.

The trickiest part, usually, is to pass a quote in the argument to the command. In this case you need to terminate single quote, add escaped quote character, start quote again, like this:

awk '$1 ~ '\''{print}'

Note, that single quote can't be escaped inside single quotes, since the "\" won't be treated as an escape character.

This is probably not related directly to your quiestion, but still useful.

maksymko
This is definitely related, thanks !The awk part is clever, I never would have thought of that by myself ^^
Isaac Clarke
Well, to be honest, I didn't think of it myself too :) I found it somewhere on the web some time ago.
maksymko
You'd still want to double quote the shellvar: awk ... '...'"$SOME_VAR"'...'. Better still, pass variables to awk using the -v option: awk -v var="$SOME_VAR" 'var ~ /pattern/ {...}'
glenn jackman
@glenn jackman Right, I forgot the double quotes, in case the var itself contains spaces or something. Regarding awk variable passing -- thanks, didn't know that.
maksymko
+1  A: 

I don't know about perl, but for bash you don't need to backslash the newline.

As for quotes, I have a (very personal) pattern that I call the "five quotes" pattern. It helps to put one quote in a string enclosed by the same kind of quotes

For instance:

doublequoted="some things "'"'"quoted"'"'" and some not"
simplequoted='again '"'"'quote this'"'"' but not that'

Note that you can freely append strings with different kinds of quotes, which is useful when you want the shell to interprete some vars but not some others:

awk -F " " '$8 ~ /\w+/{print "> ",$8, '"$SOME_SHELL_VAR"'}'

Also, I don't use the backtick anymore but the $(...)pattern which is more legible and can be nested.

USAGE=$(echo -ne "
Usage : ./$(basename $0) [-hnvV]\n
$(ls -l ${MODPATH}/reference/ | awk -F " " '$8 ~ /\w+/{print "> ",$8}')")
cadrian
Thanks for that ;)
Isaac Clarke
+1  A: 

In perl, double quoted strings will have their variables expanded.

If you write that for instance:

my $email = "[email protected]" ;

perl will try to expand @bar. If you use strict, you'll see an complain about the array bar not existing. If you don't, you'll just see a weird behavior.

So it's better to write:

my $email = '[email protected]' ;

For these types of reason, my advice is to always use single quote for strings, unless you know that you need variable expansion.

jeje
+2  A: 

In Perl, you also have q() and qq() to help you in nested quoting situations:

my $x = q(a string with 'single quotes');
my $y = qq(an $interpreted string with "double quotes");

These certainly will help you avoid "\"needlessly\"" '\'escaping\'' internal quotes.

glenn jackman
Nice ! Thanks for the info !
Isaac Clarke
draegtun
Right, thanks. You can tell where I've been spending my time recently...
glenn jackman
draegtun
+3  A: 

In bash scripting, backticks are deprecated in favor of $() in part because it is non-obvious how nested quotes and escaping are supposed to work. You may also want to take a look at Bash Pitfalls.

Jeff Bradberry
Thanks ! That's exactly what I was looking for.
Isaac Clarke