Właśnie stworzyłem ten sam skrypt biblioteki, który działa podobnie jak BusyBox. W nim używam następującej funkcji, aby sprawdzić, czy jest pozyskiwana ...
function isSourced () {
[[ "${FUNCNAME[1]}" == "source" ]] && return 0
return 1
}
Obsługiwana przez Bash tablica FUNCNAME jest zasadniczo stosem wywołań funkcji. $FUNCNAME
(lub ${FUNCNAME[0]}
) to nazwa aktualnie wykonywanej funkcji. ${FUNCNAME[1]}
to nazwa funkcji, która ją wywołała i tak dalej.
Najwyższy element jest specjalną wartością dla samego skryptu. Będzie zawierać ...
- słowo „źródło”, jeśli skrypt jest pozyskiwany
- słowo „main”, jeśli skrypt jest wykonywany ORAZ test jest wykonywany z funkcji
- „” (null), jeśli skrypt jest wykonywany ORAZ test jest wykonywany poza jakąkolwiek funkcją, to znaczy ... na poziomie samego skryptu.
Powyższa funkcja faktycznie działa tylko wtedy, gdy jest wywoływana na poziomie skryptu (co jest wszystkim, czego potrzebuję). Nie powiedzie się, jeśli zostanie wywołany z innej funkcji, ponieważ numer elementu tablicy będzie nieprawidłowy. Aby działało w dowolnym miejscu, trzeba znaleźć górę stosu i przetestować tę wartość, co jest bardziej skomplikowane.
Jeśli potrzebujesz, możesz uzyskać numer pozycji tablicy „góra stosu” za pomocą ...
local _top_of_stack=$(( ${#FUNCNAME[@]} - 1 ))
${#FUNCNAME[@]}
to liczba elementów w tablicy. Jako tablicę zerową odejmujemy 1, aby uzyskać ostatni element #.
Te trzy funkcje są używane razem, aby utworzyć ślad stosu funkcji podobny do Pythona i mogą dać ci lepszy pomysł, jak to wszystko działa ...
function inspFnStack () {
local T+=" "
local _at=
local _text="\n"
local _top=$(inspFnStackTop)
local _fn=${FUNCNAME[1]}; [[ $_fn =~ source|main ]] || _fn+="()"
local i=_top; ((--i))
#
_text+="$i item function call stack for $_fn ...\n"
_text+="| L BASH_SOURCE{BASH_LINENO called from}.FUNCNAME \n"
_text+="| ---------------------------------------------------\n"
while (( $i > 0 ))
do
_text+="| $i ${T}$(inspFnStackItem $i)\n"
T+=" "
((--i))
done
#
printf "$_text\n"
#
return 0
}
function inspFnStackItem () {
local _i=$1
local _fn=${FUNCNAME[$_i]}; [[ $_fn =~ source|main ]] || _fn+="()"
local _at="${BASH_LINENO[$_i-1]}"; [[ $_at == 1 ]] && _at="trap"
local _item="${BASH_SOURCE[$_i]}{${_at}}.$_fn"
#
printf "%s" "$_item"
return 0
}
function inspFnStackTop () {
# top stack item is 1 less than length of FUNCNAME array stack
printf "%d\n" $(( ${#FUNCNAME[@]} - 1 ))
#
return 0
}
Zauważ, że FUNCNAME, BASH_SOURCE i BASH_LINENO to 3 tablice obsługiwane przez bash, tak jakby były jedną trójwymiarową tablicą.