"functrace"가 켜져 있으면 쉘 기능이 실행되기 전에 디버그 신호에 대한 트랩이 두 번 트리거됩니다.

"functrace"가 켜져 있으면 쉘 기능이 실행되기 전에 디버그 신호에 대한 트랩이 두 번 트리거됩니다.

내 목표는 각 사용자 정의 함수를 실행하기 전에 뭔가를 하는 것입니다. 내 생각에 가장 간단한 방법은 트랩을 사용하여 신호를 디버깅하는 것입니다.

파일럿 스크립트는 정상적으로 실행됩니다.

#! /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 :)

모든 사용자 정의 함수를 캡처하고 싶기 때문에 "functrace" 옵션을 켜야 합니다. 그러나 "functrace"가 켜지면 트랩이 두 번 실행되는 것 같습니다. 예를 들어:

#! /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 :)

그렇다면 내 스크립트나 bash에 문제가 있는 걸까요? 이 두 가지 부르심을 어떻게 구별합니까?

답변1

나도 방금이 문제에 직면했습니다. 무슨 일이 일어나고 있는지 정확히 말하기는 어렵지만 호출된 함수의 컨텍스트에서 두 번째 호출이 트리거되는 것처럼 보이므로 다음과 같이 할 수 있습니다.

! /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

남은 주요 문제는 이것이 직접 재귀 호출을 잘못 억제하지만 이는 bash에서는 흔하지 않다는 것입니다.

관련 정보