Por que o Bash ignora o SIGINT se o filho atualmente em execução o manuseia?

6

O loop Bash a seguir para se eu o interromper com ^C :

(while true; do sleep 5; done)

O seguinte, no entanto, não:

(while true; do aplay test.wav; done)

A diferença, pelo que posso dizer, é que aplay captura e manipula SIGINT , enquanto sleep não.

Por que isso? O POSIX especifica esse comportamento em algum lugar (percebo que o Dash faz a mesma coisa) e, em caso afirmativo, por quê? Eu não consigo entender por que esse comportamento é desejável. De fato, como Bash pode até dizer a diferença? Devo admitir que não conheço nenhum mecanismo (pelo menos, ptrace ou /proc/ hacking) pelo qual um processo pode dizer como outro lida com sinais.

Além disso, existe uma maneira de neutralizar isso? Percebo que nem mesmo um trap 'exit 0' SIGINT antes do loop ajuda.

( EDIT : A execução dos loops em um subshell é importante, porque senão o shell pai não recebe o SIGINT .)

    
por Dolda2000 02.06.2016 / 01:00

2 respostas

5

O problema é bem explicado aqui , enquanto WCE espera e saída cooperativa e eu encorajo você a lê-lo. Basicamente, seu sinal é recebido por todos os processos em primeiro plano, isto é, o shell e o programa, sleep ou aplay. O programa sai com o código de retorno 130 se não manipular o sinal. A casca faz uma espera para a criança terminar, e vê isso, e o fato de que ela recebeu o sinal também, então sai.

Quando o programa captura o sinal, ele geralmente sai com o código 1 (como acontece com o jogo). Quando o shell aguarda o filho, ele percebe que ele não terminou devido ao sinal e, portanto, tem que assumir que o sinal era um aspecto normal do funcionamento do programa, portanto, o shell continua normalmente.

Para o seu exemplo, a melhor maneira de lidar com o jogo é verificar o código de retorno para não-zero e parar:

(while aplay test.wav; do :; done)

O artigo acima mencionado explica que um programa bem-comportado que queira capturar sigint para fazer alguma limpeza, deve então desabilitar seu manipulador, e voltar a se matar a fim de obter os sinalizadores de saída corretos definidos. / p>     

por 02.06.2016 / 14:12
-3

você poderia tentar isso, eu tive esse problema algumas vezes e idk porque isso funcionou por ele fez.

$(sigint)

isso é para dislay o resultado como um var é bash, mas para fazer isso ele tem que executá-lo e algumas vezes funciona.

    
por 02.06.2016 / 02:25

Tags