If I switch from SIGINT to any other signal (I tried SIGTERM, SIGUSR1) the trap prints “Ouch” as expected.
Aparentemente você não tentou o SIGQUIT; você provavelmente descobrirá que se comporta da mesma forma que SIGINT.
O problema é o controle do trabalho.
Nos primeiros dias do Unix, sempre que o shell colocar um processo ou pipeline em segundo plano, definiu esses processos para ignorar o SIGINT e o SIGQUIT, então eles não seriam encerrados se o usuário subseqüentemente digitado Ctrl + C (interrupção) ou Ctrl + \ (sair) para uma tarefa em primeiro plano. Quando o controle de trabalho surgiu, ele trouxe grupos de processos, e agora tudo que o shell precisa fazer é colocar o trabalho em segundo plano em um novo grupo de processos; contanto que esse não seja o grupo de processos do terminal atual, os processos não verão sinais vindos do teclado ( Ctrl + C , Ctrl + \ e Ctrl + Z (SIGTSTP)). O shell pode deixar processos em segundo plano com a disposição do sinal padrão. Na verdade, provavelmente é necessário que os processos sejam inutilizáveis por Ctrl + C quando eles são trazidos para o primeiro plano.
Mas os shells não interativos não usam controle de job. Faz sentido que um shell não interativo fosse retroceder para o velho comportamento de ignorar SIGINT e SIGQUIT para processos em segundo plano, pela razão histórica - para permitir que os processos em segundo plano continuem a ser executados, mesmo que os sinais do tipo de teclado sejam enviados para eles. E os scripts de shell são executados em shells não interativos.
E, se você olhar para o último parágrafo
sob o comando trap
em bash (1) , você verá p>
Signals ignored upon entry to the shell cannot be trapped or reset.
Então, se você executar ./scriptb.sh &
do seu prompt de comando do shell interativo ,
suas disposições de sinal são deixadas em paz
(mesmo que esteja sendo colocado em segundo plano),
e o comando trap
funciona conforme o esperado.
Mas, se você executar ./scripta.sh
(com ou sem &
),
ele executa o script em um shell não interativo.
E quando esse shell não interativo executar ./scriptb.sh &
,
ele define o processo scriptb
para ignorar a interrupção e sair.
E, portanto, o comando trap
em scriptb.sh
falha silenciosamente.