Mam plik skryptu bash, który jest umieszczony w katalogu dodanym do $ PATH, dzięki czemu mogę wywoływać skrypt z dowolnego katalogu.
W tym samym katalogu co skrypt znajduje się inny plik tekstowy. Zastanawiam się, jak odwoływać się do pliku tekstowego w skrypcie?
Na przykład, jeśli skrypt ma po prostu wyświetlać zawartość pliku tekstowego, cat textfile
nie zadziała, ponieważ podczas wywoływania skryptu z innego katalogu plik tekstowy nie zostanie znaleziony.
Odpowiedzi:
Powinny one działać tak samo, o ile nie ma dowiązań symbolicznych (w rozwinięciu ścieżki lub w samym skrypcie):
MYDIR="$(dirname "$(realpath "$0")")"
MYDIR="$(dirname "$(which "$0")")"
Dwuetapowa wersja dowolnego z powyższych:
MYSELF="$(realpath "$0")"
MYDIR="${MYSELF%/*}"
Jeśli po drodze do skryptu znajduje się dowiązanie symboliczne, wówczas
which
otrzymasz odpowiedź bez uwzględnienia rozwiązania tego linku. Jeślirealpath
nie jest domyślnie zainstalowany w twoim systemie, możesz go znaleźć tutaj .[EDYCJA]: Wydaje się, że
realpath
nie ma przewagi nadreadlink -f
sugerowanymi przez Caleba , prawdopodobnie lepiej jest użyć tego drugiego. Moje testy czasowe wskazują, że jest to rzeczywiście szybsze.źródło
realpath
pochodzi twój system. (Dla innych, którzy go nie mają, możesz użyćreadlink -f
realpath
pochodzi z przeszłościreadlink -f
(a nawetreadlink
IIRC) był w GNU coreutils (było kilka podobnych narzędzi.readlink -f
ostatecznie stał się de facto standardem);realpath
jest przechowywany tylko w celu zachowania zgodności ze skryptami, które nadal go używają.$(dirname "$(which "$0")")
nad$(dirname $0)
tym, żewhich
nie jest już obecny? Czy to nie to samo?readlink -f
nie działa na Mac OS X 10.11.6, alerealpath
działa od razu po wyjęciu z pudełka.Moje systemy nie mają,
realpath
jak sugeruje rozcietrzewiacz .Możesz to zrobić za pomocą
readlink
polecenia. Zaletą korzystania z tego nad analizowaniemwhich
lub innymi rozwiązaniami jest to, że nawet jeśli wykonywana część ścieżki lub nazwa pliku była dowiązaniem symbolicznym, można znaleźć katalog, w którym znajduje się rzeczywisty plik.Plik tekstowy można następnie odczytać w zmiennej takiej jak ta:
źródło
which
sugestii. Normalne rozwiązanie tego problemu dotyczy tylkodirname
lub kombinacjicd
iwpwd
podpowłoce. Readlink ma tutaj tę zaletę.realpath
wreadlink -f
każdym razie wydaje się być tylko opakowaniem .realpath
się różnireadlink -f
. Widzę tylko, że daje mi te same wyniki (w przeciwieństwie dowhich
).readlink -f
(z GNU coreutils) NIE wymaga istnienia ostatniego elementu ścieżkireadlink -e
, ale nie jest obsługiwany przezbusybox readlink
, co naśladuje zachowanie-e
ich-f
opcji.$0
w skrypcie będzie pełna ścieżka do skryptu, idirname
zajmie pełną ścieżkę i da ci tylko katalog, więc możesz to zrobić, aby cat textile:źródło
realpath $0
, że to nie działa , mylisz się mówiąc, że „$0
w skrypcie będzie pełna ścieżka do skryptu”.$0
to polecenie, w jakim zostało uruchomione, którym może być np../script.sh
.$(dirname "$0")
zwraca względną ścieżkę do skryptu jako część wywołanego polecenia - nie ścieżkę bezwzględną. Może to prowadzić do problemów ze skryptami zmieniającymi katalogi podczas działania.Możesz umieścić to na górze skryptu:
Źródło: http://mywiki.wooledge.org/BashFAQ/028
źródło
Próbowałem tych i prawdziwa ścieżka nie działała dla mnie. Rozwiązaniem, które wybrałem jest:
Co do tej pory działało dobrze. Chciałbym wiedzieć, czy są jakieś potencjalne problemy z tym podejściem.
źródło
SCRIPT_DIR="$( cd "$(dirname "$( readlink -f ${BASH_SOURCE[0]} )")" >/dev/null 2>&1 && pwd)"
Używam:
Który jest POSIX i powinien działać tak długo, jak nazwa katalogu
$0
nie kończy się na znakach nowego wiersza, nie jest-
i$CDPATH
nie jest ustawiona (i być może kilka innych przypadków narożnych, jeśli skrypt nie został wyszukany$PATH
).źródło
Zawsze używam
which
do znalezienia pełnej ścieżki pliku wykonywalnego z PATH. Na przykład:which python
Jeśli połączysz to z
dirname
poleceniem, otrzymasz:źródło