0

This is a Zshell question, although Bash, if it has >(command) syntax (i.e. process substitution of such kind), can hint a solution too. This really basic code explains all:

% fun() {
   setopt localtraps
   trap "echo waiting >> /tmp/out; sleep 2; echo bye >> /tmp/out; exit 1;" EXIT
   echo "My PID: $sysparams[pid]"  # needs zsh/system module
   repeat 1000; do
      read -r -t 1 line
   done
}

% exec {MYFD}> >(fun)
% exit

Above works – fun() will receive the trap, the two messages will appear in /tmp/out and "exit 1" will close the process.

My question: can be "EXIT" replaced by some actual signal? I've tried PIPE, HUP, INT, TERM and they didn't work.

1

Your code doesn't explain all. I have no idea what you're trying to do. However, I can answer the question in your title: the >(…) process does not receive a signal when the main shell exits. It exits because it reaches the end of the script, and at this point it runs the EXIT trap until it executes the exit builtin.

If you thought that the script is getting killed early because you thought the read -t 1 calls would take one second each: no, they don't, they return immediately as soon as the parent exits. When the parent exits, the read calls in the subshell are trying to read from a closed pipe, and the underlying read system call returns immediately with no data available.

  • I disagree that the question doesn't explain things. It even codifies the problem instead of using written language. Thanks for the resolution, that the background process isn't managed by main shell, and exit is caused by read detecting it cannot read from stdin and ignoring -t 1 timeout. – Digger May 13 '18 at 3:59
0

According to the manuals for both bash and zsh, yes, you can indeed trap any signal.

bash:

   trap [-lp] [[arg] sigspec ...]
          The command arg is to be read and executed when the shell receives signal(s) sigspec.  If arg is absent (and there is a single sigspec) or  -,  each  specified  signal  is
          reset  to  its  original disposition (the value it had upon entrance to the shell).  If arg is the null string the signal specified by each sigspec is ignored by the shell
          and by the commands it invokes.  If arg is not present and -p has been supplied, then the trap commands associated with each sigspec are displayed.  If  no  arguments  are
          supplied  or  if  only -p is given, trap prints the list of commands associated with each signal.  The -l option causes the shell to print a list of signal names and their
          corresponding numbers.  Each sigspec is either a signal name defined in <signal.h>, or a signal number.  Signal names are case insensitive and the SIG prefix is  optional.

zsh:

   trap [ arg ] [ sig ... ]
          arg is a series of commands (usually quoted to protect it from immediate evaluation by the shell) to be read and executed when the shell receives any of the signals speci-
          fied by one or more sig args.  Each sig can be given as a number, or as the name of a signal either with or without the string SIG in front (e.g. 1, HUP,  and  SIGHUP  are
          all the same signal).
  • My question is about something else: I'm trapping EXIT quasi-signal in process ran with >(process), when main shell exits. I would like to trap real signal that main shell uses to terminate process, but I don't know which should it be, a few most expected ones didn't work. – Digger May 11 '18 at 17:50
  • Well, it depends on how the process is being terminated. If it's because the script is done executing, that would indeed be EXIT, if it is being terminated externally, this is usually done with SIGTERM or, by indiscriminate folks, SIGKILL. – DopeGhoti May 11 '18 at 17:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.