내 목표는 각 사용자 정의 함수를 실행하기 전에 뭔가를 하는 것입니다. 내 생각에 가장 간단한 방법은 트랩을 사용하여 신호를 디버깅하는 것입니다.
파일럿 스크립트는 정상적으로 실행됩니다.
#! /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에서는 흔하지 않다는 것입니다.