6

I'm struggling to find clear, unambiguous information about how the trap command works.

In particular, is the effect of trap local to the script where it appears? I had always assumed this to be the case, but I've seen statements to the contrary. Does trap affect other shell scripts called from the current one? Does it affect binary programs?

2

2 Answers 2

4

You can test it out quickly enough:

$ cat test.sh trap : INT HUP USR1 sleep 10h $ ./test.sh & [1] 29668 $ grep SigCgt /proc/$(pgrep test.sh)/status SigCgt: 0000000000010203 $ grep SigCgt /proc/$(pgrep sleep)/status SigCgt: 0000000000000000 

So trap doesn't affect binaries.

What about scripts?

$ cat blah.sh #! /bin/bash grep SigCgt /proc/$$/status $ cat test.sh #! /bin/bash trap : INT HUP USR1 ./blah.sh $ ./test.sh SigCgt: 0000000000010002 

So something's being caught. But wait!

$ ./blah.sh SigCgt: 0000000000010002 

Looks like those signals are handled anyway.


The manpage has this to say:

 When a simple command other than a builtin or shell function is to be executed, it is invoked in a separate execution environment that consists of the following. Unless otherwise noted, the values are inherited from the shell. ... · traps caught by the shell are reset to the values inherited from the shell's parent, and traps ignored by the shell are ignored 

If you want to convert that bitmask to a set of signals, try:

HANDLED_SIGS=$(awk '/SigCgt/{print "0x"$2}' /proc/$PID/status) for i in {0..31} do (( (1 << i) & $HANDLED_SIGS )) && echo $((++i)) $(/bin/kill --list=$i); done | column 

In this case, the set of signals that were handled without trap were:

$ HANDLED_SIGS=0x0000000000010002 $ for i in {0..31}; do (( (1 << i) & $HANDLED_SIGS )) && echo $((++i)) $(/bin/kill --list=$i); done | column 2 INT 17 CHLD 
10
  • I tried grep /proc/$$/status after various combinations of trap. I seem to get SigCgt: 43817efb in all cases. What the heck...? Commented Dec 2, 2014 at 12:24
  • @MathematicalOrchid Looks like you ran that grep in an interactive shell, which already traps a variety of signals. Commented Dec 2, 2014 at 12:49
  • Nope. It's running from a script file, that successively turns on various traps and prints out the result after each one. Commented Dec 2, 2014 at 12:52
  • @MathematicalOrchid Can you post the script? (at, say, paste.ubuntu.com or a Github gist) Commented Dec 2, 2014 at 12:53
  • See my other "answer". Commented Dec 2, 2014 at 13:12
0

This is not an answer, but...

$ cat Trap.sh #!/bin/bash echo "Trap.sh is PID $$" trap -p grep Sig /proc/$$/status trap 'echo SIGINT' SIGINT trap -p grep Sig /proc/$$/status trap 'echo SIGTERM' SIGTERM trap -p grep Sig /proc/$$/status trap 'echo SIGUSR1' SIGUSR1 trap -p grep Sig /proc/$$/status $ ./Trap.sh Trap.sh is PID 13887 SigQ: 0/63517 SigPnd: 0000000000000000 SigBlk: 0000000000010000 SigIgn: 0000000000000004 SigCgt: 0000000043817efb trap -- 'echo SIGINT' SIGINT SigQ: 0/63517 SigPnd: 0000000000000000 SigBlk: 0000000000010000 SigIgn: 0000000000000004 SigCgt: 0000000043817efb trap -- 'echo SIGINT' SIGINT trap -- 'echo SIGTERM' SIGTERM SigQ: 0/63517 SigPnd: 0000000000000000 SigBlk: 0000000000010000 SigIgn: 0000000000000004 SigCgt: 0000000043817efb trap -- 'echo SIGINT' SIGINT trap -- 'echo SIGUSR1' SIGUSR1 trap -- 'echo SIGTERM' SIGTERM SigQ: 0/63517 SigPnd: 0000000000000000 SigBlk: 0000000000010000 SigIgn: 0000000000000004 SigCgt: 0000000043817efb 

I have no idea what this means. My guess is that Bash is trapping everything, and then deciding what to do inside the trap routine.

2
  • I think you should add this to the question. And apparently it's set to 0x43817efb only after the trap -p (if you remove that, or shift it to after the grep, you get the correct value). Dunno why. Commented Dec 2, 2014 at 13:23
  • How odd... I have no idea why it would do that. Commented Dec 2, 2014 at 13:34

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.