Herdando traps de sinal de Bash

3

Estou com dificuldades para encontrar informações claras e não ambíguas sobre como o comando trap funciona.

Em particular, o efeito de trap local no script é exibido? Eu sempre supus que fosse esse o caso, mas vi declarações em contrário. O trap afeta outros scripts de shell chamados do atual? Isso afeta programas binários?

    
por MathematicalOrchid 02.12.2014 / 12:08

2 respostas

1

Você pode testá-lo com rapidez suficiente:

$ 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

Portanto, trap não afeta os binários.

E os 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

Então, algo está sendo pego. Mas espere!

$ ./blah.sh 
SigCgt: 0000000000010002

Parece que esses sinais são manipulados de qualquer maneira.

A página do manual tem isto a dizer:

   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

Se você quiser converter esse bitmask em um conjunto de sinais, tente:

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

Nesse caso, o conjunto de sinais que foram manipulados sem trap foi:

$ 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
    
por 02.12.2014 / 12:40
0

Esta não é uma resposta, mas ...

$ 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

Eu não tenho ideia do que isso significa. Meu palpite é que o Bash está prendendo tudo e decidindo o que fazer dentro da rotina de traps.

    
por 02.12.2014 / 14:07

Tags