To rozwiązanie dotyczy tylko bash, a nie tcsh. Zauważ, że najczęściej podawana odpowiedź ${BASH_SOURCE[0]}
nie zadziała, jeśli spróbujesz znaleźć ścieżkę z funkcji.
Przekonałem się, że ta linia zawsze działa, niezależnie od tego, czy plik jest pobierany czy uruchamiany jako skrypt.
echo ${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}
Jeśli chcesz podążać za dowiązaniami symbolicznymi, użyj readlink
ścieżki powyżej, rekursywnie lub nierekurencyjnie.
Oto skrypt do wypróbowania i porównania z innymi proponowanymi rozwiązaniami. Wywołaj jako source test1/test2/test_script.sh
lub bash test1/test2/test_script.sh
.
#
# Location: test1/test2/test_script.sh
#
echo $0
echo $_
echo ${BASH_SOURCE}
echo ${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}
cur_file="${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}"
cur_dir="$(dirname "${cur_file}")"
source "${cur_dir}/func_def.sh"
function test_within_func_inside {
echo ${BASH_SOURCE}
echo ${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}
}
echo "Testing within function inside"
test_within_func_inside
echo "Testing within function outside"
test_within_func_outside
#
# Location: test1/test2/func_def.sh
#
function test_within_func_outside {
echo ${BASH_SOURCE}
echo ${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}
}
Powód, dla którego działa jednolinijka, jest wyjaśniony przez użycie BASH_SOURCE
zmiennej środowiskowej i jej powiązania FUNCNAME
.
BASH_SOURCE
Zmienna tablicowa, której członkowie są źródłowymi nazwami plików, w których zdefiniowane są odpowiednie nazwy funkcji powłoki w zmiennej tablicowej FUNCNAME. Funkcja powłoki $ {FUNCNAME [$ i]} jest zdefiniowana w pliku $ {BASH_SOURCE [$ i]} i wywołana z $ {BASH_SOURCE [$ i + 1]}.
FUNCNAME
Zmienna tablicowa zawierająca nazwy wszystkich funkcji powłoki znajdujących się obecnie na stosie wywołań wykonawczych. Element o indeksie 0 jest nazwą każdej aktualnie wykonywanej funkcji powłoki. Najniższy element (ten o najwyższym indeksie) to „main”. Ta zmienna istnieje tylko podczas wykonywania funkcji powłoki. Przypisania do FUNCNAME nie działają i zwracają status błędu. Jeśli FUNCNAME jest rozbrojony, traci swoje specjalne właściwości, nawet jeśli zostanie następnie zresetowany.
Tej zmiennej można używać z BASH_LINENO i BASH_SOURCE. Każdy element FUNCNAME ma odpowiadające elementy w BASH_LINENO i BASH_SOURCE do opisania stosu wywołań. Na przykład $ {FUNCNAME [$ i]} został wywołany z pliku $ {BASH_SOURCE [$ i + 1]} w linii $ {BASH_LINENO [$ i]}. Wbudowane narzędzie wywołujące wyświetla bieżący stos połączeń, korzystając z tych informacji.
[Źródło: instrukcja Bash]