O script Bash não vê o SIGHUP?

10

Eu tenho o seguinte script:

#!/bin/bash
echo "We are $$"
trap "echo HUP" SIGHUP
cat    # wait indefinitely

Quando eu envio SIGHUP (usando kill -HUP pid ), nada acontece.

Se eu alterar o script ligeiramente:

#!/bin/bash
echo "We are $$"
trap "kill -- -$BASHPID" EXIT    # add this
trap "echo HUP" SIGHUP
cat    # wait indefinitely

... então o script faz a coisa echo HUP assim que sai (quando eu pressiono Ctrl + C):

roger@roger-pc:~ $ ./hupper.sh 
We are 6233
^CHUP

O que está acontecendo? Como devo enviar um sinal (não necessariamente tem que ser SIGHUP ) para este script?

    
por Roger Lipscombe 23.08.2017 / 11:52

2 respostas

18

O manual do Bash afirma:

If bash is waiting for a command to complete and receives a signal for which a trap has been set, the trap will not be executed until the command completes.

Isso significa que, apesar de o sinal ser recebido por bash quando você o envia, sua interceptação em SIGHUP só será chamada quando cat terminar.

Se esse comportamento não for desejado, use bash builtins (por exemplo, read + printf em um loop em vez de cat ) ou use trabalhos em segundo plano (consulte Resposta de Stéphane ).

    
por 23.08.2017 / 12:55
8

@xhienne já explicou por que , mas se você quisesse que o sinal agisse imediatamente (e não saia do script), você poderia alterar seu código para:

#! /bin/bash -
interrupted=true
trap 'interrupted=true; echo HUP' HUP

{ cat <&3 3<&- & pid=$!; } 3<&0

while
  wait "$pid"
  ret=$?
  "$interrupted"
do
  interrupted=false
done
exit "$ret"

A pequena dança com descritores de arquivo é para contornar o fato de que bash redireciona stdin para /dev/null para comandos iniciados em segundo plano.

    
por 23.08.2017 / 13:15

Tags