trap para depurar o sinal foi evocado duas vezes antes da função shell ser executada quando 'functrace' está ativado

1

Meu objetivo é fazer algo antes que toda função definida pelo usuário seja executada. O método mais direto que vem à minha cabeça é usar o trap para depurar o sinal.

O script do piloto é executado bastante bem:

#! /bin/env bash

function welcome { echo "Welcome :)"; }

trap 'declare -F ${BASH_COMMAND%% *} >/dev/null && \
      echo "[Running] ${BASH_COMMAND%% *}"' DEBUG

welcome
## will output:
# [Running] welcome
# Welcome :)

Como eu quero capturar todas as funções definidas pelo usuário, a opção 'functrace' deve estar ativada. No entanto, uma vez que 'functrace' esteja ativado, parece que a interceptação será evocada duas vezes. Por exemplo:

#! /bin/env bash
set -o functrace

function welcome { echo "Welcome :)"; }

trap 'declare -F ${BASH_COMMAND%% *} >/dev/null && \
      echo "[Running] ${BASH_COMMAND%% *}"' DEBUG

welcome
## will output:
# [Running] welcome
# [Running] welcome
# Welcome :)

Então, qual é o problema com meu script ou bash? Como distinguir essas duas evocações?

    
por ghbore 14.04.2015 / 15:52

1 resposta

2

Acabei de encontrar este problema também. É difícil dizer exatamente o que está acontecendo, mas parece que a segunda invocação é acionada dentro do contexto da função sendo chamada, então você poderia fazer:

! /bin/env bash
set -o functrace

function welcome { echo "Welcome :)"; }


function __debug_trap {
  declare -F ${BASH_COMMAND%% *} >/dev/null
  # funcname[0] is __debug_trap; funcname[1] is the next function on stack
  if ! [[ "${BASH_COMMAND%% *}" == "${FUNCNAME[1]}" ]]; then
    echo "[Running] ${BASH_COMMAND%% *}"
  fi
}

trap __debug_trap DEBUG

welcome
echo not in function

#bash test.sh
#[Running] welcome
#[Running] echo
#Welcome :)
#[Running] echo
#not in function

A principal questão remanescente é que isso suprime incorretamente as chamadas recursivas diretamente; mas esses não são comuns no bash.

    
por 21.04.2015 / 01:24

Tags