1#! /bin/sh 2 3# func_exit STATUS 4# exit with status 5func_exit () 6{ 7 (exit $1); exit $1 8} 9 10# func_fatal_error message 11# outputs to stderr a fatal error message, and terminates the program. 12func_fatal_error () 13{ 14 echo "test-echo.sh: *** $1" 1>&2 15 echo "test-echo.sh: *** Stop." 1>&2 16 func_exit 1 17} 18 19# Ensure an 'echo' command that does not interpret backslashes. 20# Test cases: 21# echo '\n' | wc -l prints 1 when OK, 2 when KO 22# echo '\t' | grep t > /dev/null has return code 0 when OK, 1 when KO 23# This problem is a weird heritage from SVR4. BSD got it right (except that 24# BSD echo interprets '-n' as an option, which is also not desirable). 25# Nowadays the problem occurs in 4 situations: 26# - in bash, when the shell option xpg_echo is set (bash >= 2.04) 27# or when it was built with --enable-usg-echo-default (bash >= 2.0) 28# or when it was built with DEFAULT_ECHO_TO_USG (bash < 2.0), 29# - in zsh, when sh-emulation is not set, 30# - in ksh (e.g. AIX /bin/sh and Solaris /usr/xpg4/bin/sh are ksh instances, 31# and HP-UX /bin/sh and IRIX /bin/sh behave similarly), 32# - in Solaris /bin/sh and OSF/1 /bin/sh. 33# We try the following workarounds: 34# - for all: respawn using $CONFIG_SHELL if that is set and works. 35# - for bash >= 2.04: unset the shell option xpg_echo. 36# - for bash >= 2.0: define echo to a function that uses the printf built-in. 37# - for bash < 2.0: define echo to a function that uses cat of a here document. 38# - for zsh: turn sh-emulation on. 39# - for ksh: alias echo to 'print -r'. 40# - for ksh: alias echo to a function that uses cat of a here document. 41# - for Solaris /bin/sh and OSF/1 /bin/sh: respawn using /bin/ksh and rely on 42# the ksh workaround. 43# - otherwise: respawn using /bin/sh and rely on the workarounds. 44# When respawning, we pass --no-reexec as first argument, so as to avoid 45# turning this script into a fork bomb in unlucky situations. 46have_echo= 47if echo '\t' | grep t > /dev/null; then 48 have_echo=yes # Lucky! 49fi 50# Try the workarounds. 51# Respawn using $CONFIG_SHELL if that is set and works. 52if test -z "$have_echo" \ 53 && test "X$1" != "X--no-reexec" \ 54 && test -n "$CONFIG_SHELL" \ 55 && test -f "$CONFIG_SHELL" \ 56 && $CONFIG_SHELL -c 'echo '\t' | grep t > /dev/null'; then 57 exec $CONFIG_SHELL "$0" --no-reexec "$@" 58 exit 127 59fi 60# For bash >= 2.04: unset the shell option xpg_echo. 61if test -z "$have_echo" \ 62 && test -n "$BASH_VERSION" \ 63 && (shopt -o xpg_echo; echo '\t' | grep t > /dev/null) 2>/dev/null; then 64 shopt -o xpg_echo 65 have_echo=yes 66fi 67# For bash >= 2.0: define echo to a function that uses the printf built-in. 68# For bash < 2.0: define echo to a function that uses cat of a here document. 69# (There is no win in using 'printf' over 'cat' if it is not a shell built-in.) 70if test -z "$have_echo" \ 71 && test -n "$BASH_VERSION"; then \ 72 if type printf 2>/dev/null | grep / > /dev/null; then 73 # 'printf' is not a shell built-in. 74echo () 75{ 76cat <<EOF 77$* 78EOF 79} 80 else 81 # 'printf' is a shell built-in. 82echo () 83{ 84 printf '%s\n' "$*" 85} 86 fi 87 if echo '\t' | grep t > /dev/null; then 88 have_echo=yes 89 fi 90fi 91# For zsh: turn sh-emulation on. 92if test -z "$have_echo" \ 93 && test -n "$ZSH_VERSION" \ 94 && (emulate sh) >/dev/null 2>&1; then 95 emulate sh 96fi 97# For ksh: alias echo to 'print -r'. 98if test -z "$have_echo" \ 99 && (type print) >/dev/null 2>&1; then 100 # A 'print' command exists. 101 if type print 2>/dev/null | grep / > /dev/null; then 102 : 103 else 104 # 'print' is a shell built-in. 105 if (print -r '\told' | grep told > /dev/null) 2>/dev/null; then 106 # 'print' is the ksh shell built-in. 107 alias echo='print -r' 108 fi 109 fi 110fi 111if test -z "$have_echo" \ 112 && echo '\t' | grep t > /dev/null; then 113 have_echo=yes 114fi 115# For ksh: alias echo to a function that uses cat of a here document. 116# The ksh manual page says: 117# "Aliasing is performed when scripts are read, not while they are executed. 118# Therefore, for an alias to take effect, the alias definition command has 119# to be executed before the command which references the alias is read." 120# Because of this, we have to play strange tricks with have_echo, to ensure 121# that the top-level statement containing the test starts after the 'alias' 122# command. 123if test -z "$have_echo"; then 124bsd_echo () 125{ 126cat <<EOF 127$* 128EOF 129} 130alias echo=bsd_echo 2>/dev/null 131fi 132if test -z "$have_echo" \ 133 && echo '\t' | grep t > /dev/null; then 134 have_echo=yes 135fi 136if test -z "$have_echo"; then 137 unalias echo 2>/dev/null 138fi 139# For Solaris /bin/sh and OSF/1 /bin/sh: respawn using /bin/ksh. 140if test -z "$have_echo" \ 141 && test "X$1" != "X--no-reexec" \ 142 && test -f /bin/ksh; then 143 exec /bin/ksh "$0" --no-reexec "$@" 144 exit 127 145fi 146# Otherwise: respawn using /bin/sh. 147if test -z "$have_echo" \ 148 && test "X$1" != "X--no-reexec" \ 149 && test -f /bin/sh; then 150 exec /bin/sh "$0" --no-reexec "$@" 151 exit 127 152fi 153if test -z "$have_echo"; then 154 func_fatal_error "Shell does not support 'echo' correctly. Please install GNU bash and set the environment variable CONFIG_SHELL to point to it." 155fi 156if echo '\t' | grep t > /dev/null; then 157 : # Works fine now. 158else 159 func_fatal_error "Shell does not support 'echo' correctly. Workaround does not work. Please report this as a bug to bug-gnulib@gnu.org." 160fi 161if test "X$1" = "X--no-reexec"; then 162 shift 163fi 164 165# This command determines the exit code. 166echo '\t' | grep t > /dev/null 167