Por que o comportamento diferente do trapping EXIT vs INT

6

Executando bash 4.3 no Kubuntu Trusty 64 bit. Por favor, veja os dois arquivos a seguir:

trapping-int.sh

#! /bin/bash
trap "echo Exiting" INT
cat </dev/urandom >/dev/null
echo Hello

trapping-exit.sh

#! /bin/bash
trap "echo Exiting" EXIT
cat </dev/urandom >/dev/null
echo Hello

Agora, ao pressionar ^ C, o trapping SIGINT imprime Exiting e Hello , enquanto que o trapping EXIT imprime apenas Exiting , mas com uma nova linha extra:

$ ./trapping-int 
^CExiting
Hello
$ ./trapping-exit 
^CExiting

$

Eu gostaria de saber o motivo do comportamento diferente. Além disso, posso assumir com segurança que EXIT é sempre chamado mesmo que INT seja dado por ^ C?

Comentar a última linha em ambos os scripts faz com que o trapping do SIGINT não imprima mais o Hello, mas o trapping EXIT ainda imprime a nova linha extra. Eu gostaria de saber a razão aqui também.

Obrigado!

    
por jamadagni 25.10.2014 / 13:52

1 resposta

9

Primeiro, um resumo de alguns fatos sobre sinais e o shell:

  • Quando você pressiona CTRL + C no teclado, uma SIGINT é enviada para todos os processos no grupo de processos do processo em primeiro plano. Nesse caso, significa que um SIGINT será recebido pelo comando cat e pelo processo bash que interpreta seu script.

  • Quando você interceptar INT , um INT não fará mais com que o processo seja encerrado, a menos que você saia explicitamente em seu manipulador.

  • Quando você captura EXIT , seu argumento é executado não em um sinal específico, mas na saída do shell.

O comportamento de trapping-int.sh é direto, dados esses fatos, pois sabemos que acontece o seguinte:

  • O processo cat recebe um SIGINT e sua execução é finalizada.
  • O processo bash recebe um SIGINT e executa seu manipulador de sinal, imprimindo "Saindo \ n" para STDOUT .
  • O processo bash continua a execução e imprime "Olá \ n" para STDOUT .
  • O processo bash é encerrado quando chega ao final do script.

O comportamento de trapping-exit.sh também é bastante direto:

  • O processo cat recebe um SIGINT e sua execução é finalizada.
  • O processo bash recebe um SIGINT e, como não há manipulador de sinal, ele também sai. Ele executa / não / executa o comando echo , pois está saindo imediatamente após receber o sinal.
  • Como o processo bash está sendo finalizado, o manipulador EXIT é executado, imprimindo "Exiting \ n" para STDOUT .

A questão restante é "de onde vem a nova linha?" Acredito que o que está acontecendo é que o próprio bash está instalando um manipulador SIGINT que imprime uma nova linha.

No seu script trapping-int.sh , você substitui o manipulador do Bash por SIGINT , para que você não receba a nova linha extra.

    
por 25.10.2014 / 16:14