SIGINT não está limpo em “$ {FUNCNAME [@]}”

6

Pegue o script a seguir, interrompido pela entrada do teclado ^C , conforme mostrado:

$ function a() { echo "Performing"; sleep 10; echo "Performed"; }
$ a
Performing
^C
$ echo "${FUNCNAME[@]}"
a source

Se repetirmos o SIGINT durante a função a muitas vezes, acabaremos com este cenário:

...

$ a
Performing
^C
$ a
Performing
^C
$ echo "${FUNCNAME[@]}"
a a a a a a a a a source

Para demonstrar o problema, vamos ter outra função, b , que fornece uma função message_error , também definida abaixo:

$ function message_error() {
>   local MESSAGE="$1"
>
>   # FUNCNAME[1], as [0] is 'message_error', gets the calling function
>   echo "[[ ERROR ]] ${FUNCNAME[1]}: $MESSAGE"
>   echo "Rest of the stack: ${FUNCNAME[@]}"
>}
$ function b() { message_error "Oh no"; }
$ b
[[ ERROR ]] b: Oh no
Rest of the stack: message_error b a a a a a a a a a source

Embora a função seja chamada no source , a aparece como a função de chamada. Como você pode ver, todas essas funções a foram encerradas. No entanto, eles permanecem no array FUNCNAME.

Por que isso? Como posso removê-lo depois que o SIGINT não consegue removê-lo? Observe que todas as funções são provenientes de uma grande coleção de funções comumente usadas, ~/.bash_functions , se a origem das funções afetar como elas interpretam o SIGINT.

    
por Nick Bull 15.07.2016 / 14:48

1 resposta

1

Como FUNCNAME é uma matriz somente leitura , provavelmente não há como remover itens. Parece que unset FUNCNAME funciona, mas também quebra o comportamento especial FUNCNAME de bash .

A prevenção de FUNCNAME lixo pode ser feita usando trap :

$ trap : SIGINT
$ function a() {  echo "Performing"; sleep 10; echo "Performed"; } 
$ a
Performing
^C
$ echo %"${FUNCNAME[@]}"%
%%

Para desativar a prevenção acima, faça trap - SIGINT .

    
por 23.10.2016 / 08:33