Odwołanie się do pliku względem wykonywanego skryptu


97

W pisanym przeze mnie skrypcie bash używam sourcedo dołączania zmiennej zdefiniowanej w pliku konfiguracyjnym. Skrypt do wykonania to act.sh, a skrypt do wykonania sourced to act.conf.sh, więc act.shmam:

source act.conf.sh

Jednak działa to tylko wtedy, gdy działa act.shw katalogu zawierającym go, ponieważ act.conf.shodnosi się do pliku umieszczonego w katalogu roboczym. Czy istnieje rozwiązanie, które sprawi, że będzie odnosił się do pliku względem wykonywanego skryptu bez wywoływania cd? Dzięki.

Odpowiedzi:


121

Zobacz: BASH FAQ wpis nr 28: „Jak określić lokalizację mojego skryptu? Chcę czytać niektóre pliki konfiguracyjne z tego samego miejsca”.

Żadne rozwiązanie nie będzie działać w 100% przypadków:

Należy zdać sobie sprawę, że w ogólnym przypadku ten problem nie ma rozwiązania. Każde podejście, o którym być może słyszałeś, i każde podejście, które zostanie szczegółowo opisane poniżej, ma wady i będzie działać tylko w określonych przypadkach. Przede wszystkim staraj się całkowicie uniknąć problemu, nie polegając na lokalizacji skryptu!

Jeśli musisz napisać bardzo wielokrotnego użytku, narzędzia, a następnie biorąc poprawną ścieżkę jako parametr do skryptu będzie najbardziej wiarygodna metoda .

Zakładając, że twój skrypt będzie uruchamiany tylko z pewnych powłok i tylko przy wymaganej odrobinie elastyczności, prawdopodobnie możesz złagodzić tę paranoję. Nadal dobrze jest spojrzeć na swoje opcje. Istnieją wspólne wzorce, których ludzie używają, a które są szczególnie problematyczne.

W szczególności FAQ zaleca unikanie bardzo często używanej $0zmiennej:

Nic, co czyta $0, nigdy nie będzie kuloodporne, ponieważ $0samo w sobie jest zawodne.

Zamiast tego możesz użyć $BASH_SOURCE. Coś takiego:

source "${BASH_SOURCE%/*}/act.conf.sh"

Rozwiązanie to ma też pewne zastrzeżenia. Zajrzyj na stronę z często zadawanymi pytaniami, aby zobaczyć kompromisy między różnymi rozwiązaniami. Wydaje się, że zalecają cdw połączeniu z $BASH_SOURCEw przypadkach, w których będzie to działać dla Ciebie, ponieważ pojawia się przydatny błąd, gdy nie rozwija się prawidłowo.


1
Dzięki, skorzystałbym readlink. Nie byłem w stanie określić słów kluczowych do wyszukania, więc opublikowałem tutaj pytanie ...
Ryan Li

9
Czy możesz dodać odpowiednie informacje do odpowiedzi na wypadek, gdyby zdarzyło się, że bash FAQ nie działa?
Merlyn Morgan-Graham

3
Link zaleca :,cd "${BASH_SOURCE%/*}" || exit lub read somevar < "${BASH_SOURCE%/*}/etc/somefile", Link zdecydowanie odradza $0 „Nic, co brzmi 0 USD, nigdy nie będzie kuloodporne, ponieważ samo 0 USD jest zawodne”.
ThorSummoner,

10
Co robi% / * po BASH_SOURCE i jak?
Silicomancer



5

Spróbuj wykonać następujące czynności:

source ${BASH_SOURCE[0]/%act.sh/act.conf.sh}

1

Zwykle dodaję to do moich skryptów.

cd $(dirname $BASH_SOURCE)

Następnie cały kolejny kod jest wykonywany względem ścieżki skryptu.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.