zsh-workers
 help / color / mirror / code / Atom feed
* TRAPEXIT question
@ 1999-08-03 18:50 Greg Klanderman
  1999-08-04  4:40 ` Bart Schaefer
  0 siblings, 1 reply; 6+ messages in thread
From: Greg Klanderman @ 1999-08-03 18:50 UTC (permalink / raw)
  To: Zsh list


Hi,

I'd like to define a funtion that when invoked defines a TRAPEXIT
function to save my directory stack and history before the shell
exits.  Unfortunately, it seems that if TRAPEXIT is defined from
within a shell function or even from a "source"d file, the exit 
hook gets called when the function exits or sourced file finishes,
rather than when the shell itself exits.

Is there any way around this?

thanks,

Greg


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: TRAPEXIT question
  1999-08-03 18:50 TRAPEXIT question Greg Klanderman
@ 1999-08-04  4:40 ` Bart Schaefer
  1999-08-04  7:47   ` Peter Stephenson
  1999-08-04 21:54   ` Greg Klanderman
  0 siblings, 2 replies; 6+ messages in thread
From: Bart Schaefer @ 1999-08-04  4:40 UTC (permalink / raw)
  To: greg, Zsh list

On Aug 3,  2:50pm, Greg Klanderman wrote:
} Subject: TRAPEXIT question
}
} Unfortunately, it seems that if TRAPEXIT is defined from
} within a shell function or even from a "source"d file, the exit 
} hook gets called when the function exits or sourced file finishes

Yes, this is correct.  However, how that trap behaves depends upon how
you define it.  To quote the manual:

     Note that traps defined with the `trap' builtin are slightly
     different from those defined as ``TRAP'NAL () { ... }', as the
     latter have their own function environment (line numbers, local
     variables, etc.) while the former use the environment of the
     command in which they were called.  For example,

     `trap 'print $LINENO' DEBUG'

     will print the line number of command executed after it has run,
     while

     `TRAPDEBUG() { print $LINENO; }'

     will always print the number zero.

This has an interesting side-effect in the case of the EXIT trap.  If you
use the `TRAPEXIT() { ... }' function form, then other traps set within the
trap itself have the context of the TRAPEXIT function; but if you use the
`trap "..." EXIT' form, traps set within the trap have as their context a
function that has already exited -- and as a consequence they get set in
the next context up, which can even be the top-level shell.

(I don't know if any other shell behaves this way; I know bash does *not*.
The new LOCAL_TRAPS option in 3.1.6 doesn't appear to affect it.)

Anyway, this means that either of the following forms create a function
that will install an exit trap on the calling shell:

	trip() { trap 'trap "echo trip" EXIT' EXIT }
	trip() { trap 'TRAPEXIT() { echo trip }' EXIT }

Which one you use probably depends on how hairy you want the quoting to
get.  It might be easiest to define yet another function that is the real
body of the trap, and simply call it:

	troll() { print "Who's that trip-trapping over MY bridge?" }
	trip() { trap 'trap troll EXIT' EXIT }

Now that I've answered the question ... can you tell me what's wrong with
using a .zlogout file instead?

-- 
Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: TRAPEXIT question
  1999-08-04  4:40 ` Bart Schaefer
@ 1999-08-04  7:47   ` Peter Stephenson
  1999-08-04 21:54   ` Greg Klanderman
  1 sibling, 0 replies; 6+ messages in thread
From: Peter Stephenson @ 1999-08-04  7:47 UTC (permalink / raw)
  To: Zsh list

"Bart Schaefer" wrote:
> This has an interesting side-effect in the case of the EXIT trap.  If you
> use the `TRAPEXIT() { ... }' function form, then other traps set within the
> trap itself have the context of the TRAPEXIT function; but if you use the
> `trap "..." EXIT' form, traps set within the trap have as their context a
> function that has already exited -- and as a consequence they get set in
> the next context up, which can even be the top-level shell.
> 
> (I don't know if any other shell behaves this way; I know bash does *not*.
> The new LOCAL_TRAPS option in 3.1.6 doesn't appear to affect it.)

ksh works this way, as far as the trap builtin is concerned, which is why
zsh does.  bash doesn't seem to regard EXIT traps as applying to functions
at all.  Neither of them have TRAP functions, which were presumably
introduced to avoid the messy quoting syntax, although as you pointed out
you can have the real function defined somewhere else (but then you still
lose the effect of being in the surrounding context).  In the early days
zsh called them both with a separate function environment, and this is
different from any other shell; only the trap builtin was fixed, however,
since if you define a function trap it's natural that it should have a
function environment.

-- 
Peter Stephenson <pws@ibmth.df.unipi.it>       Tel: +39 050 844536
WWW:  http://www.ifh.de/~pws/
Dipartimento di Fisica, Via Buonarroti 2, 56127 Pisa, Italy


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: TRAPEXIT question
  1999-08-04  4:40 ` Bart Schaefer
  1999-08-04  7:47   ` Peter Stephenson
@ 1999-08-04 21:54   ` Greg Klanderman
  1999-08-05  8:34     ` Peter Stephenson
  1 sibling, 1 reply; 6+ messages in thread
From: Greg Klanderman @ 1999-08-04 21:54 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: greg, Zsh list


>>>>> "Bart" == Bart Schaefer <schaefer@candle.brasslantern.com> writes:

> 	trip() { trap 'trap "echo trip" EXIT' EXIT }
> 	trip() { trap 'TRAPEXIT() { echo trip }' EXIT }

Cool.  I was thinking I might try something like that next.

> Now that I've answered the question ... can you tell me what's wrong with
> using a .zlogout file instead?

Yup, that'd probably work just fine...

So is there an easy way to indirect through the value of a variable?
I know I can use eval, but, for example, in BASH you can do

foo=bar
bar=baz
echo ${!foo}   -> baz

thanks,
Greg


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: TRAPEXIT question
  1999-08-04 21:54   ` Greg Klanderman
@ 1999-08-05  8:34     ` Peter Stephenson
  1999-08-05 10:51       ` Bart Schaefer
  0 siblings, 1 reply; 6+ messages in thread
From: Peter Stephenson @ 1999-08-05  8:34 UTC (permalink / raw)
  To: greg, Zsh list

Greg Klanderman wrote:
> So is there an easy way to indirect through the value of a variable?
> I know I can use eval, but, for example, in BASH you can do
> 
> foo=bar
> bar=baz
> echo ${!foo}   -> baz

The zsh equivalent (from 3.1.6) is

  foo=bar
  bar=baz
  echo ${(P)foo}

There may be some reason why didn't use !, which I think was mentioned at
some point, but I can't remember what it was.

-- 
Peter Stephenson <pws@ibmth.df.unipi.it>       Tel: +39 050 844536
WWW:  http://www.ifh.de/~pws/
Dipartimento di Fisica, Via Buonarroti 2, 56127 Pisa, Italy


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: TRAPEXIT question
  1999-08-05  8:34     ` Peter Stephenson
@ 1999-08-05 10:51       ` Bart Schaefer
  0 siblings, 0 replies; 6+ messages in thread
From: Bart Schaefer @ 1999-08-05 10:51 UTC (permalink / raw)
  To: Zsh list

On Aug 5, 10:34am, Peter Stephenson wrote:
} Subject: Re: TRAPEXIT question
}
}   echo ${(P)foo}
} 
} There may be some reason why didn't use !, which I think was mentioned at
} some point, but I can't remember what it was.

zagzig[21] echo ${!foo}
zsh: event not found: foo


-- 
Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~1999-08-05 10:51 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-08-03 18:50 TRAPEXIT question Greg Klanderman
1999-08-04  4:40 ` Bart Schaefer
1999-08-04  7:47   ` Peter Stephenson
1999-08-04 21:54   ` Greg Klanderman
1999-08-05  8:34     ` Peter Stephenson
1999-08-05 10:51       ` Bart Schaefer

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).