Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

zsh-4.1.1 and trap '...' DEBUG: a bug or a feature?



We are finishing up a book on shell programming, and in the course of
documenting the handling of DEBUG traps, I found unexpected behavior
in zsh-4.1.1, which I have installed on about 20 flavors of Unix at my
site.

Consider the following test file:

	% cat debug-trap
	trap 'echo This is an EXIT trap' EXIT
	trap 'echo This is a DEBUG trap' DEBUG
	pwd
	pwd
	pwd
	pwd

Now watch this behavior (recorded on an IA-64 system, unless otherwise
noted).

First, bash:

	% /local/build/icc/bash-2.05b.p7/bash --version
	GNU bash, version 2.05b.0(1)-release (ia64-unknown-linux-gnu)

	# That is the latest bash version 2.05b with all 7 released patches installed

	% /local/build/icc/bash-2.05b.p7/bash debug-trap
	This is a DEBUG trap
	/tmp
	This is a DEBUG trap
	/tmp
	This is a DEBUG trap
	/tmp
	This is a DEBUG trap
	/tmp
	This is a DEBUG trap
	This is an EXIT trap

Tests showed that the bash behavior depends critically on the patch
level; I'm in the process of upgrading my systems to have 2.05b with
all 7 patches.

Next zsh-4.1.1 (the latest):

	% zsh debug-trap
	This is a DEBUG trap
	/tmp
	This is a DEBUG trap
	/tmp
	This is a DEBUG trap
	/tmp
	This is a DEBUG trap
	/tmp
	This is a DEBUG trap
	This is an EXIT trap
	This is a DEBUG trap

Notice that zsh takes one final DEBUG trap that bash does not.  That
seems undesirable, because the EXIT trap code is documented in sh and
ksh to be the last code executed, and is invoked in response to either
normal termination, or an explicit exit statement.

Is this a bug, or a feature?

>From the zsh manual in the info system, I found this paragraph:

     If SIG is ZERR then ARG will be executed after each command with a
     nonzero exit status.  If SIG is DEBUG then ARG will be executed
     after each command.  If SIG is 0 or EXIT and the trap statement is
     executed inside the body of a function, then the command ARG is
     executed after the function completes.  If SIG is 0 or EXIT and
     the trap statement is not executed inside the body of a function,
     then the command ARG is executed when the shell terminates.

The last sentence implies that it is a feature, but perhaps it should
be reconsidered, and made to do what bash and ksh93 do, or else an
explanation should be offered in the manual of why a different choice
was made. Remember, unnecessary implementation differences create
portability headaches, and make life hard for documenters and authors
who have to explain, or even defend, the differences to their readers.

I checked that the extra invocation of the DEBUG trap does not spoil
the intended exit code:

	% cat exit.sh
	#! /bin/sh
	trap "ls -l $0; echo 'Check the exit status: it should be 49.'" EXIT
	trap "echo This is a DEBUG trap" DEBUG

	echo Leaving $0 with exit code 49
	exit 49

	% zsh ./exit.sh
	This is a DEBUG trap
	Leaving ./exit.sh with exit code 49
	This is a DEBUG trap
	-rwxrwxr-x  1 beebe staff 162 Mar 23 10:44 ./exit.sh
	This is a DEBUG trap
	Check the exit status: it should be 49.
	This is a DEBUG trap

	% echo $?
	49

POSIX (IEEE Std 1003.1-2001) does not include the DEBUG trap, so there
is no independent guidance there.

-------------------------------------------------------------------------------
- Nelson H. F. Beebe                    Tel: +1 801 581 5254                  -
- University of Utah                    FAX: +1 801 581 4148                  -
- Department of Mathematics, 110 LCB    Internet e-mail: beebe@xxxxxxxxxxxxx  -
- 155 S 1400 E RM 233                       beebe@xxxxxxx  beebe@xxxxxxxxxxxx -
- Salt Lake City, UT 84112-0090, USA    URL: http://www.math.utah.edu/~beebe  -
-------------------------------------------------------------------------------



Messages sorted by: Reverse Date, Date, Thread, Author