Uwaga: Aby uzyskać rozwiązanie zgodne z POSIX, zobacz tę odpowiedź .
${BASH_SOURCE[0]}
(lub, prościej, $BASH_SOURCE
[1]
) zawiera (potencjalnie względną) ścieżkę zawierającego skryptu we wszystkich scenariuszach wywołania, zwłaszcza gdy skrypt jest pozyskiwany , co nie jest prawdą $0
.
Ponadto, jak wskazuje Charles Duffy , wywołujący $0
może ustawić dowolną wartość.
Z drugiej strony, $BASH_SOURCE
może być puste, jeśli nie ma nazwanego pliku; na przykład:
echo 'echo "[$BASH_SOURCE]"' | bash
Poniższy przykład ilustruje to:
Skrypt foo
:
#!/bin/bash
echo "[$0] vs. [${BASH_SOURCE[0]}]"
$ bash ./foo
[./foo] vs. [./foo]
$ ./foo
[./foo] vs. [./foo]
$ . ./foo
[bash] vs. [./foo]
$0
jest częścią specyfikacji powłoki POSIX, podczas gdy BASH_SOURCE
, jak nazwa sugeruje, jest specyficzna dla Bash.
[1] Literatura: ${BASH_SOURCE[0]}
vs$BASH_SOURCE
:
Bash pozwala na elemencie bazowym 0
wystąpienia tablicy zmiennej używając skalarnego notacji: zamiast pisać ${arr[0]}
, można napisać $arr
; innymi słowy: jeśli odniesiesz się do zmiennej tak, jakby była skalarem , otrzymasz element pod indeksem 0
.
Korzystanie z tej funkcji przesłania fakt, że $arr
jest to tablica, dlatego popularny linter z kodem powłoki shellcheck.net wyświetla następujące ostrzeżenie (w chwili pisania tego tekstu):
SC2128: Rozszerzenie tablicy bez indeksu daje tylko pierwszy element.
Na marginesie: chociaż to ostrzeżenie jest pomocne, może być bardziej precyzyjne, ponieważ niekoniecznie otrzymasz pierwszy element: 0
zwracany jest konkretnie element w indeksie , więc jeśli pierwszy element ma wyższy indeks - który jest możliwe w Bash - otrzymasz pusty ciąg; spróbuj 'a[1]='hi'; echo "$a"'
.
(Natomiast zsh
, nigdy renegat, rzeczywiście robi powrotu pierwszy element, niezależnie od jej indeksu).
Możesz zrezygnować z tej funkcji ze względu na jej niejasność, ale działa ona przewidywalnie i, mówiąc pragmatycznie, rzadko, jeśli w ogóle, będziesz potrzebować dostępu do indeksów innych niż 0
zmienna tablicowa ${BASH_SOURCE[@]}
.
BASH_SOURCE
został dodany w bash-3.0-alpha. Możesz go nie mieć, w zależności od systemu testowania. Okazało się, że brakuje go zarówno we wczesnym Solarisie, jak i na OS X. Zobacz także return: can return: can only 'return' from a function or source script on U & L.SE.