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

Re: child PID in TRAPCHLD?



On Dec 11,  1:32am, Anthony Heading wrote:
} 
} I'm trying to catch the termination of background commands.

I know this seems blasphemous on a shell mailing list, but at some
point you've just got to learn a language that was designed with
this kind of thing in mind (perl, python) rather than try to wedge
everything into the shell.

} Using TRAPCHLD seems sensible

Be aware that the trap isn't tripped until after the shell has done
all of its internal job-reaping, so by the time you get control there
is nothing left of the job to manipulate.

On the other hand, that does mean that ...

} perhaps zsh could be enhanced to set $! to that PID locally inside the
} TRAPCHLD handler?

... is not impossible, although it'd be unlike other shells.

} but I can't see a way to identify the PID (or job id) of the command
} that has ended. Am I missing something?

You can find out indirectly by examining the $jobstates array from
the zsh/parameter module to find out what's NOT there.

    zmodload zsh/parameter
    typeset -ga joblist
    TRAPCLD () {
      emulate -L zsh
      local i pid
      for (( i=$#joblist ; i; --i ))
      do
        pid=$joblist[i]; 
        [[ -n ${jobstates[(R)*:$pid=*]} ]] && continue
	joblist[i]=()
	print $pid exited
      done
    }
    repeat 4 do sleep 3 & joblist+=( $! ); done

Note for this you have to maintain your own $joblist array of the PIDs
that you care about.  There's also an inevitable race condition in the
event that the background job exits before you can add it to $joblist.

-- 



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