EXIT traps in interactive shells

2012-07-28 Thread Maarten Billemont
Trapping on EXIT is a really convenient way of cleaning up after yourself when 
your script ends.

The nice thing about it is that you don't need to handle all sorts of signals, 
handle them, and re-throw them.  It makes for a single clean point to define 
your exit handlers.

Unfortunately, I've noticed that EXIT handlers don't play so nice in 
interactive shells.  This is of particular interest when you background a 
subshell from them:

{
trap 'rm tempfile' EXIT
dowork tempfile
} &
...
kill $!

This works fine from a script (non-interactive) but not when performed from the 
prompt.

Here's some demonstrational code:

interactive:

~ $ { trap 'echo exiting' EXIT; sleep 5; } & sleep 1; kill $!
[1] 59061
[1]+  Terminated: 15  { trap 'echo exiting' EXIT; sleep 5; }

non-interactive:

~ $ bash -c '{ trap "echo exiting" EXIT; sleep 5; }' & sleep 1; kill $!
[1] 59168
exiting
[1]+  Terminated: 15  bash -c '{ trap "echo exiting" EXIT; sleep 5; }'

So, why is this, is this a bug, and we have this fixed?  I like being able to 
rely on my EXIT handler.

Cheers,
Maarten.

smime.p7s
Description: S/MIME cryptographic signature


Re: AIX and Interix also do early PID recycling.

2012-07-28 Thread Chet Ramey
On 7/27/12 9:50 AM, Michael Haubenwallner wrote:

> With attached patch I haven't been able to break the testcase below so far
> on that AIX 6.1 box here.
> 
> But still, the other one using the $()-childs still fails.

Try the attached patch for that.

Chet
-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRUc...@case.eduhttp://cnswww.cns.cwru.edu/~chet/


*** ../bash-4.2-patched/execute_cmd.c	2012-05-02 12:02:27.0 -0400
--- execute_cmd.c	2012-07-28 18:14:33.0 -0400
***
*** 752,758 
  
  	/* XXX - this is something to watch out for if there are problems
! 	   when the shell is compiled without job control. */
! 	if (already_making_children && pipe_out == NO_PIPE &&
! 	last_made_pid != last_pid)
  	  {
  	stop_pipeline (asynchronous, (COMMAND *)NULL);
--- 776,784 
  
  	/* XXX - this is something to watch out for if there are problems
! 	   when the shell is compiled without job control.  Don't worry about
! 	   whether or not last_made_pid == last_pid; already_making_children
! 	   tells us whether or not there are unwaited-for children to wait
! 	   for and reap. */
! 	if (already_making_children && pipe_out == NO_PIPE)
  	  {
  	stop_pipeline (asynchronous, (COMMAND *)NULL);