Hello, Fernando Ferreira wrote: > I found out that gnulib-tools, > invoked by bootstrap to generate the gnulib-comp.m4 file, had a little > but vital bug that inserted these extraneous characters instead of the > desired behavior. The faulty lines are these, lines 2170 to 2180 on > gnulib/gnulib-tool, that is downloaded from the gnulib CVS by the > bootstrap script: > > if test "$auxdir" != "build-aux"; then > sed_replace_build_aux=' > :a > /AC_CONFIG_FILES(.*:build-aux\/.*)/{ > > s|AC_CONFIG_FILES(\(.*\):build-aux/\(.*\))|AC_CONFIG_FILES(\1:'"$auxdir"'/\2)| > ba > }' > sed_replace_build_aux=`echo "$sed_replace_build_aux" | sed -e 1d > -e 's/^ *//'` > else > sed_replace_build_aux= > fi > > > When it assigns sed_replace_build_aux with 'foo \1 bar \2', and then > echoes it, instead of the desired effect of keeping it as literal '\1' > and '\2' it changes it to the ASCII character 1 and 2.
It is generally impossible to write reliable shell-scripts using 'echo', when this 'echo' commands interprets backslahes. I'm not inclined to check or rewrite the 500 echo commands in gnulib-tool. Instead, I'm applying this workaround. Tested with bash, zsh, ksh, and /bin/sh of Linux, MacOS X, AIX, HP-UX, IRIX, Solaris, OSF/1. libtool.m4 also tries other workarounds: searching for an 'echo' program in $PATH:/usr/ucb (but how is this better than 'cat'?) or using a built-in 'print -r' command (which shells except ksh have this?) or using 'printf' (is that portable nowadays?). 2007-06-22 Bruno Haible <[EMAIL PROTECTED]> * gnulib-tool (echo): Ensure the echo primitive does not interpret backslashes. * tests/test-echo.sh: New file. *** gnulib-tool 22 Jun 2007 18:16:40 -0000 1.234 --- gnulib-tool 23 Jun 2007 01:59:31 -0000 *************** *** 410,415 **** --- 410,512 ---- fi } + # Ensure an 'echo' command that does not interpret backslashes. + # Test cases: + # echo '\n' | wc -l prints 1 when OK, 2 when KO + # echo '\t' | grep t > /dev/null has return code 0 when OK, 1 when KO + # This problem is a weird heritage from SVR4. BSD got it right. + # Nowadays the problem occurs in 4 situations: + # - in bash, when the shell option xpg_echo is set, + # - in zsh, when sh-emulation is not set, + # - in ksh (e.g. AIX /bin/sh and Solaris /usr/xpg4/bin/sh are ksh instances, + # and HP-UX /bin/sh and IRIX /bin/sh behave similarly), + # - in Solaris /bin/sh and OSF/1 /bin/sh. + # We try the following workarounds: + # - for all: respawn using $CONFIG_SHELL if that is set and works. + # - for bash: unset the shell option xpg_echo. + # - for zsh: turn sh-emulation on. + # - for ksh: alias echo to a function that uses cat of a here document. + # - for Solaris /bin/sh: respawn using /bin/ksh and rely on the ksh workaround. + # - otherwise: respawn using /bin/sh and rely on the workarounds. + # When respawning, we pass --no-reexec as first argument, so as to avoid + # turning this script into a fork bomb in unlucky situations. + have_echo= + if echo '\t' | grep t > /dev/null; then + have_echo=yes # Lucky! + fi + # Try the workarounds. + # Respawn using $CONFIG_SHELL if that is set and works. + if test -z "$have_echo" \ + && test "X$1" != "X--no-reexec" \ + && test -n "$CONFIG_SHELL" \ + && test -f "$CONFIG_SHELL" \ + && $CONFIG_SHELL -c 'echo '\t' | grep t > /dev/null'; then + exec $CONFIG_SHELL "$0" --no-reexec "$@" + exit 127 + fi + # For bash: unset the shell option xpg_echo. + if test -z "$have_echo" \ + && test -n "$BASH_VERSION" \ + && (shopt -o xpg_echo; echo '\t' | grep t > /dev/null) 2>/dev/null; then + shopt -o xpg_echo + have_echo=yes + fi + # For zsh: turn sh-emulation on. + if test -z "$have_echo" \ + && test -n "$ZSH_VERSION" \ + && (emulate sh) >/dev/null 2>&1; then + emulate sh + fi + # For ksh: alias echo to a function that uses cat of a here document. + # The ksh manual page says: + # "Aliasing is performed when scripts are read, not while they are executed. + # Therefore, for an alias to take effect, the alias definition command has + # to be executed before the command which references the alias is read." + # Because of this, we have to play strange tricks with have_echo, to ensure + # that the top-level statement containing the test start after the 'alias' + # command. + if test -z "$have_echo"; then + bsd_echo () + { + cat <<EOF + $* + EOF + } + alias echo=bsd_echo 2>/dev/null + fi + if test -z "$have_echo" \ + && echo '\t' | grep t > /dev/null; then + have_echo=yes + fi + if test -z "$have_echo"; then + unalias echo 2>/dev/null + fi + # For Solaris /bin/sh and OSF/1 /bin/sh: respawn using /bin/ksh. + if test -z "$have_echo" \ + && test "X$1" != "X--no-reexec" \ + && test -f /bin/ksh; then + exec /bin/ksh "$0" --no-reexec "$@" + exit 127 + fi + # Otherwise: respawn using /bin/sh. + if test -z "$have_echo" \ + && test "X$1" != "X--no-reexec" \ + && test -f /bin/sh; then + exec /bin/sh "$0" --no-reexec "$@" + exit 127 + fi + if test -z "$have_echo"; then + func_fatal_error "Shell does not support 'echo' correctly. Please install GNU bash and set the environment variable CONFIG_SHELL to point to it." + fi + if echo '\t' | grep t > /dev/null; then + : # Works fine now. + else + func_fatal_error "Shell does not support 'echo' correctly. Workaround does not work. Please report this as a bug to [EMAIL PROTECTED]" + fi + if test "X$1" = "X--no-reexec"; then + shift + fi + # Command-line option processing. # Removes the OPTIONS from the arguments. Sets the variables: # - mode list or import or create-testdir or create-megatestdir