-1

I run into this weird behavior of trap.

According to trap's manpage:

When a subshell is entered, traps that are not being ignored are set to the default actions. This does not imply that the trap command cannot be used within the subshell to set new traps.

This is how I interpret it:

  • If a script traps signal A, its subshell will also trap signal A but with a default action.
  • The subshell can also specify another action to trap that same signal

To test my understanding, I have two scripts:

outerscript.sh

#!/bin/bash

trap "echo SIGINT in outer" SIGINT
echo PID of outer process: $$
echo -----------;
./innerscript.sh

innerscript.sh

#!/bin/bash

echo start inner script
echo PID of inner process: $$
trap "SIGINT in inner, do graceful shutdown" SIGINT
sleep 10s
echo done inner process

Then I run the outerscript with ./outerscript.sh The outerscript will then call the innerscript and create a subshell as shown in the picture

enter image description here

During the sleep command, I send a SIGINT with kill -SIGINT <pid>

The result is different based on the PID receiving the signal

  1. PID to receive signal is that of outerscript

    Note that I still have to wait for the sleep command to complete

    done inner process
    SIGINT in outer
    
  2. PID to receive signal is that of innerscript

    Note that I still have to wait for the sleep command to complete

    SIGINT: command not found
    done inner process
    
  3. PID to receive signal is that of sleep

    Note that I DON'T have to wait for the sleep command to complete

    done inner process
    

Question

In case 2), why do I get that error? I expected innerscript to trigger its trap function.

In case 3), why does it even trigger innerscript's trap function? I expected it to just kill itself and return normally to the inner script process.

  • 2
    The error in case 2 is because you have trap "SIGINT ... rather than trap "echo SIGINT ... – icarus Aug 11 '19 at 5:38
  • 2
    In case 3 it is not triggering the trap function, it is stopping the sleep, then going onto the next line, the echo done inner process – icarus Aug 11 '19 at 5:40
  • oh boy, thanks for pointing out the missing echo function. I can't believe I struggled with this for hours. – Tran Triet Aug 11 '19 at 5:49
  • If you could post this as an answer, I'd gladly mark it as the solution. – Tran Triet Aug 11 '19 at 5:50
  • 1
    Upvoted because it's a very well-described problem and a good example of how to write a question that contains all the information to be answerable (as per How to Ask). I'm sure most of us – at some time in our lives – have spent hours struggling with problems that had similarly trivial causes. – Anthony Geoghegan Aug 12 '19 at 15:57
2

There are 2 questions. The error in case 2 is because there is no command called SIGINT on the system. The OP had

trap "SIGINT in inner, do graceful shutdown" SIGINT

but probably the desired command was

trap "echo SIGINT in inner, do graceful shutdown" SIGINT

The other question asks why the inner scripts trap function is invoked, however it is not. The sleep process is killed, the script moves onto the next line.

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