I had an alias defined at one point as follows: alias rmutt="/usr/local/bin/mutt -Z || /usr/local/bin/mutt -f '=inbox'" , where the first invocation of mutt checks to see if any of my "important" mailboxes have new mail, and opens mutt in the first such mailbox if there is one, and the second invocation opens mutt in my default inbox. The problem I found myself running into was that I often, while composing messages, use ^Z to suspend mutt (or, more usually, vi) to go look at something else, and then return to mutt; for some reason, if I do that, then when mutt finally returns, it returns with an exit code of 23 rather than 0 even though everything worked correctly--the end result is that, if there _is_ mail in one of my important mailboxes, and I happen to suspend mutt during that session, then when I try to quit mutt, it immediately reopens because the first half of the condition above evaluates as false. I tried to work around this by changing the alias to a function definition as follows: function rmutt () { TRAPEXIT () { case $? in 0|23) : ;; *) /usr/local/bin/mutt -f '=inbox' ;; esac } /usr/local/bin/mutt -Z } . Now, whenever I run the rmutt function, there is a long pause before it executes; once it is done running (that is, once I exit mutt), any attempt to use command substitution in a function causes the subshell to dump core, as follows: (astaroth)/tmp/zsh_is_wonky: ll total 0 (astaroth)/tmp/zsh_is_wonky: function wonky () { echo hello } (astaroth)/tmp/zsh_is_wonky: wonky hello (astaroth)/tmp/zsh_is_wonky: ll total 0 (astaroth)/tmp/zsh_is_wonky: function wonky () { echo `echo hello` } hello (astaroth)/tmp/zsh_is_wonky: ll total 0 (astaroth)/tmp/zsh_is_wonky: rmutt <...quit out of mutt...> (astaroth)/tmp/zsh_is_wonky: ll total 0 (astaroth)/tmp/zsh_is_wonky: function wonky () { echo hello } (astaroth)/tmp/zsh_is_wonky: wonky hello (astaroth)/tmp/zsh_is_wonky: ll total 0 (astaroth)/tmp/zsh_is_wonky: function wonky () { echo `echo hello` } (astaroth)/tmp/zsh_is_wonky: wonky (astaroth)/tmp/zsh_is_wonky: ll total 2464 -rw------- 1 sweth staff 1259376 Sep 7 17:20 core (astaroth)/tmp/zsh_is_wonky: . It doesn't matter if I use `...` or $(...) notation, and I don't get this behaviour for command substitution that I enter directly on the command-line. Also of note, I can run the rmutt function as many times as desired, and nothing directly untoward happens; if I run rmutt, run a function that uses command substitution (and thus dumps core as above), and then run rmutt again, however, my main zsh process dumps core and I get booted off the system. Finally, sometimes (I haven't been able to figure out under what circumstances exactly), rather than dumping core, the process in question will return "fatal error: out of memory"; when I get that behaviour it persists until the end of that shell, but is otherwise identical to the coredump behaviour. This is using: (astaroth)/tmp/zsh_is_wonky: echo $ZSH_VERSION 3.1.9 ; I know that 4.0.2 is out now, but I just haven't had a chance to install it yet. Also, I finally realized that I was making my problem much harder than I needed to, because I could get rid of the TRAPEXIT and just do: rmutt () { /usr/local/bin/mutt -Z; case $? in 0|23) : ;; *) /usr/local/bin/mutt -f '=action' ;; esac } ; I had originally tried trying to trap the SIGTSTP, which is why I became fixated on using a trap, but obviously that's not the best solution by a long shot. I'd still like to know how TRAPEXIT is really supposed to work, though, and what is causing this odd behaviour. -- Sweth. -- Sweth Chandramouli ; President, Idiopathic Systems Consulting