Subject: /bin/sh messes up quoting when ${var:+$var} substitution includes quotes
To: NetBSD Userlevel Technical Discussion List <tech-userlevel@NetBSD.ORG>
From: Greg A. Woods <woods@weird.com>
List: tech-userlevel
Date: 06/21/2004 18:34:54
I've encountered a bug in how /bin/sh handles parameter quoting when the
text in a "${FOO:+$BAR}" variable substitution includes quotes in $BAR.
This problem affects both netbsd-1-6 and netbsd-2-0.
I think this is an un-reported bug and that this post should be a PR,
but I wanted to ask first as even though I've been unable to find any
similar PR, I'm not confident that my searching could have been
successful.
I discovered this through a little trick with variable expansion that I
to show the actual quoting on debug output in shell scripts (and to make
the debug output cut & pastable). I recently had a need to use the
"${VAR:+expansion}" form where the expansion included a variable that
expanded to text including double-quote characters, and I found this
failed with /bin/sh, but worked with /bin/ksh.
Here's a test script. As-is it'll bail out with what appears to be a
weird sed error when executed with /bin/sh, but it runs silently when
run with /bin/ksh:
$ sh ~/src/tquote.sh
sed: unknown option -- g
usage: sed script [-anE] [file ...]
sed [-an] [-e script] ... [-f script_file] ... [file ...]
$ ksh ~/src/tquote.sh
$
Change the 'DEBUG=false' to 'DEBUG=true' to see the debug output with quoting.
-------------------- tquotevar.sh --------------------
DEBUG=false
BUILD_FLAGS="CFLAGS=\"-O2 -W\""
BUILD_DEBUG="\"-Werror -g\""
if $DEBUG; then
DQ="'" # used to wrap multi-token params
DEBUG_ECHO="echo"
else
DQ=""
DEBUG_ECHO=""
fi
# this is OK with sh and ksh
#
${DEBUG_ECHO} \
sed -e ${DQ}'s/^/to test/'${DQ} \
-e ${DQ}"s/$/build with: ${BUILD_FLAGS} but leave ${BUILD_DEBUG} out/"${DQ} < /dev/null
# this is also OK with sh and ksh
#
${DEBUG_ECHO} \
sed -e ${DQ}'s/^/to test/'${DQ} \
-e ${DQ}"s/$/build with: ${BUILD_FLAGS} but leave ${BUILD_DEBUG:-${BUILD_DEBUG}} out/"${DQ} < /dev/null
# this one fails with sh but works with ksh
#
${DEBUG_ECHO} \
sed -e ${DQ}'s/^/to really test/'${DQ} \
-e ${DQ}"s/$/build with: ${BUILD_FLAGS}${BUILD_DEBUG:+ and ${BUILD_DEBUG}}/"${DQ} < /dev/null
----------------------------------------
--
Greg A. Woods
+1 416 218-0098 VE3TCP RoboHack <woods@robohack.ca>
Planix, Inc. <woods@planix.com> Secrets of the Weird <woods@weird.com>