From: Eric Blake Date: Sun, 7 Jun 2009 04:03:16 +0000 (-0600) Subject: Improve documentation on trap pitfalls. X-Git-Tag: v2.64~47 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=22e57e5c5ec8d566321d33536b9e6e47e8084580;p=thirdparty%2Fautoconf.git Improve documentation on trap pitfalls. * doc/autoconf.texi (Limitations of Builtins) : Mention new Posix 2008 requirement on trap, and dash bug in implementing it. Mention various shell bugs with traps defined inside subshells. Mention older bash limitation with single-command exit trap. : Mention another 'set -e' limitation. Reported by Jens Schmidt. Signed-off-by: Eric Blake --- diff --git a/ChangeLog b/ChangeLog index ddac2578b..01fdd3d35 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2009-06-06 Eric Blake + + Improve documentation on trap pitfalls. + * doc/autoconf.texi (Limitations of Builtins) : Mention new + Posix 2008 requirement on trap, and dash bug in implementing it. + Mention various shell bugs with traps defined inside subshells. + Mention older bash limitation with single-command exit trap. + : Mention another 'set -e' limitation. + Reported by Jens Schmidt. + 2009-06-06 Jim Meyering Improve testsuite --help diff --git a/doc/autoconf.texi b/doc/autoconf.texi index 215c86475..81bce0716 100644 --- a/doc/autoconf.texi +++ b/doc/autoconf.texi @@ -16188,6 +16188,16 @@ does not print @samp{two}. One workaround is to use @samp{if test -n "$foo"; then exit 1; fi} rather than @samp{test -n "$foo" && exit 1}. Another possibility is to warn @acronym{BSD} users not to use @samp{sh -e}. +When @samp{set -e} is in effect, a failed command substitution in +Solaris @command{/bin/sh} cannot be ignored, even with @samp{||}. + +@example +$ @kbd{/bin/sh -c 'set -d; foo=`false` || echo foo; echo bar'} +$ @kbd{bash -c 'set -d; foo=`false` || echo foo; echo bar'} +foo +bar +@end example + Portable scripts should not use @samp{set -e} if @command{trap} is used to install an exit handler. This is because Tru64/OSF 5.1 @command{sh} sometimes enters the trap handler with the exit status of the command @@ -16345,7 +16355,11 @@ Posix says that @samp{trap - 1 2 13 15} resets the traps for the specified signals to their default values, but many common shells (e.g., Solaris @command{/bin/sh}) misinterpret this and attempt to execute a ``command'' named @command{-} when the specified conditions arise. -There is no portable workaround, except for @samp{trap - 0}, for which +Posix 2008 also added a requirement to support @samp{trap 1 2 13 15} to +reset traps, as this is supported by a larger set of shells, but there +are still shells like @command{dash} that mistakenly try to execute +@command{1} instead of resetting the traps. Therefore, there is no +portable workaround, except for @samp{trap - 0}, for which @samp{trap '' 0} is a portable substitute. Although Posix is not absolutely clear on this point, it is widely @@ -16390,6 +16404,31 @@ $ @kbd{exit} @noindent Fortunately, this bug only affects @command{trap}. +Several shells fail to execute an exit trap that is defined inside a +subshell, when the last command of that subshell is not a builtin. A +workaround is to use @samp{exit $?} as the shell builtin. + +@example +$ @kbd{bash -c '(trap "echo hi" 0; /bin/true)'} +hi +$ @kbd{/bin/sh -c '(trap "echo hi" 0; /bin/true)'} +$ @kbd{/bin/sh -c '(trap "echo hi" 0; /bin/true; exit $?)'} +hi +@end example + +@noindent +Likewise, older implementations of @command{bash} failed to preserve +@samp{$?} across an exit trap consisting of a single cleanup command. + +@example +$ @kbd{bash -c 'trap "/bin/true" 0; exit 2'; echo $?} +2 +$ @kbd{bash-2.05b -c 'trap "/bin/true" 0; exit 2'; echo $?} +0 +$ @kbd{bash-2.05b -c 'trap ":; /bin/true" 0; exit 2'; echo $?} +2 +@end example + @item @command{true} @c ----------------- @prindex @command{true}