Another example of why Bourne shell quoting makes me grumpy

December 22, 2006

Following up the previous case, here's something we ran into recently.

Imagine that you want to pull lines out of /etc/shadow for specific login names; you'd use, for example, 'grep "^${UNAME}:" /etc/shadow'. Now imagine that some of your login names include '$', so you want to generate a version of $UNAME with the '$' quoted.

So what do you have to write? It turns out that you need this:

nname=`echo ${UNAME} | sed 's/\\$/\\\\$/'`

You might innocently expect that you can write the sed expression just as you would on the command line, as 'sed 's/\$/\\$/'', but if you try that it doesn't work. This is because backquotes perform one level of de-escaping on their own, so that you can escape backquotes.

(And you have to be able to escape backquotes because otherwise you couldn't nest backquote expansions. Eliminating this problem is why modern versions of the Bourne shell allow you to write $(...) instead; paired delimiters can nest without confusion.)

Any time you have multiple levels of escaping and de-escaping at work, you have entered into a land of pain. People are not good at counting escapes, or at keeping track of what each level of processing will do and what the results will look like, or even at remembering when quoting is and isn't needed. Making them do it anyways results in bugs, voodoo programming (add escapes until the code magically starts working), and often security bugs.

And this is why I get grumpy about any language that requires multiple levels of escaping and de-escaping, the Bourne shell included. (I more or less permanently soured on TCL after similar experiences with an early version, although I've heard that current versions have fixed this.)

Written on 22 December 2006.
« Something to avoid in callback email address verification
Weekly spam summary on December 23rd, 2006 »

Page tools: View Source, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Fri Dec 22 23:01:30 2006
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.