I really tried to find a better title for this question. I am open for suggestions.I've written a bash script that traps EXIT and calls a function if that signal is received. It calls the same function when a file called stop exists. Here it is:#!/bin/bashTAIL_PID=0CAT_PID=0DEVICE=/dev/ttyACM0WDIR=plasmaLOGFILE=$WDIR/$(date +%Y%m%d_%H%M%S.log)CMDFILE=$WDIR/toDevicefunction kill_tail{  if [ $TAIL_PID -ne 0 ]  then    kill $TAIL_PID    TAIL_PID=0    echo killed tail  fi}function kill_cat{  if [ $CAT_PID -ne 0 ]  then    kill $CAT_PID    CAT_PID=0    echo killed cat  fi}function on_die{  echo 't 0' >> $DEVICE  kill_tail  kill_cat  echo stopped logging}trap on_die EXIT# mount plasma oven directory if it is not already mountedmountpoint -q $WDIR || sshfs user@server:plasma $WDIR    # see if device is available/wait for devicewhile [ ! -c $DEVICE ]do  sleep 1doneecho Found controller# stop output, remove start and stop filesecho 't 0' >> $DEVICErm $WDIR/start $WDIR/stop# outer loopwhile [ 1 ]do  while [ ! -f $WDIR/start ]  do    sleep 1  done  rm $WDIR/start  # stop output  echo 't 0' >> $DEVICE  # pass commands to device  # but clear existing commands first  > $CMDFILE  tail -f $CMDFILE > $DEVICE &  TAIL_PID=$!  echo tail PID =  $TAIL_PID  # start logging  cat $DEVICE >> $LOGFILE &  CAT_PID=$!  echo cat PID =  $CAT_PID  # start output  echo 't 1000' >> $DEVICE  echo started logging to  $LOGFILE  while [ ! -f $WDIR/stop ]  do    sleep 1  done  rm $WDIR/stop  on_diedone # end of outer loopWhen I run this script, after touch start, it gives me different output depending on whether I CTRL-C or touch stop. This is the output after CTRL-Cing:killed tailkilled catstopped loggingThis is the output after touch stop:killed tailkilled catstopped logging./mountPlasma: line 93: 21200 Terminated              tail -f $CMDFILE > $DEVICE./mountPlasma: line 93: 21201 Terminated              cat $DEVICE >> $LOGFILEWhy? The same function is called, and I would expect the same output from both calls to on_die. The output indicates that the two extra messages are emitted on line 93, which is done # end of outer loop (the line number does not exactly match the code above, as I had to remove a few lines for this post).As I am very unexperienced with bash, I don't know if there are any side-effects to this. Both tailand cat are killed as expected.
bash: different output between CTRL-C vs ordered cleanup
bash;kill
When you hit Ctrl-C, the running script gets SIGINT and propagates it to it's children, whereas on regular exit it would send the default SIGTERM (from the function registered with EXIT).That said, there is a big difference between Ctrl-C and the stop condition. While the exit handler function gets called in both cases the actual events are completely different. In the case of SIGINT, the child processes are killed by that one (or at least are likely to be) and the shell interpreting the script doesn't have much chance to report this state change. In the other case it catches SIGCHLD from the terminated programs and displays the information message. Now, you can get the message on SIGINT as well, provided you give the interpreting shell enough time to check (more precisely - since I don't think that shell would be leaving zombie processes around in this situation - to report the status of) its child processes. One way to do it would be using the wait builtin to actively wait for all or specified processes to change state. Blowing up the exit handler (e.g. with another sleep) might be an option too, but note that this actually is sort of a race condition between the interpreter terminating and checking on its children (hence the blocking wait is the safe way to do it).