$ bash -c "trap \"echo INT\" INT; sleep 3" & pid=$!; sleep 1; kill -INT $pid; wait
[1] 27811
INT
[1]+ Done bash -c "trap \"echo INT\" INT; sleep 3"
$ (bash -c "trap \"echo INT\" INT; sleep 3" & pid=$!; sleep 1; kill -INT $pid; wait)
Você pode explicar por que o SIGINT
manipulador não é invocado no segundo caso?
https://www.gnu.org/software/libc/manual/html_node/Job-Control.html
Geralmente é ativado em shells interativos e desativado em não interativos:
Nesse caso... aparentemente o controle de trabalho está desabilitado e
$-
não pode ser invocado:https://www.gnu.org/software/bash/manual/html_node/Job-Control-Basics.html
Ou seja, quando o controle de trabalho está habilitado, cada pipeline é executado em um grupo de processos separado.
pgid.sh
:Um dos trabalhos é um trabalho de primeiro plano, o resto são de segundo plano.
Os trabalhos em segundo plano não devem estar vinculados ao shell que os iniciou. Se você sair de um shell, eles continuarão em execução. Como tal, eles não devem ser interrompidos por
SIGINT
, não por padrão. Quando o controle de tarefas está ativado, isso é realizado automaticamente, pois as tarefas em segundo plano são executadas em grupos de processos separados. Quando o controle de trabalho está desabilitado,bash
faz com que os comandos assíncronos ignoremSIGINT
e não permite que eles (se forembash
scripts) o substituam.Ou seja, aqui:
o trabalho em segundo plano (
bash -c "trap 'echo INT' INT; sleep 3"
) é executado por um shell interativo, que tem o controle de trabalho ativado. Como resultado, o job em background recebeSIGINT
.Quando o envolvemos em um shell não interativo sem controle de trabalho:
bash -c "trap 'echo INT' INT; sleep 3"
ignoraSIGINT
etrap ... INT
também é ignorado.Isso pode ser confirmado desta forma:
Algumas citações relevantes:
https://www.gnu.org/software/bash/manual/html_node/Signals.html
https://www.gnu.org/software/bash/manual/html_node/Bourne-Shell-Builtins.html#index-trap
https://www.gnu.org/software/bash/manual/html_node/Job-Control-Basics.html