Jak pisząc skrypt bash, jak uzyskać bezwzględną ścieżkę lokalizacji bieżącego pliku?

16

Załóżmy, że mam plik bash o nazwie myBash.bash. Znajduje się w:

/myDirect/myFolder/myBash.bash

Teraz chcę użyć ciągu /myDirect/myFolder(lokalizacji myBash.bash) w skrypcie. Czy istnieje polecenie, którego mogę użyć, aby znaleźć tę lokalizację?

Edycja: Chodzi o to, że chcę skonfigurować folder zip z kodem, który można uruchomić za pomocą skryptu bash w tym pliku zip. Znam względne ścieżki pliku kodu w tym pliku zip, ale nie ścieżki absolutne i potrzebuję ich. Jednym ze sposobów byłoby na stałe zakodować ścieżkę lub wymagać podania ścieżki pliku jako zmiennej. Jednak łatwiej byłoby mi, gdyby plik bash mógł dowiedzieć się, gdzie jest on sam, a następnie utworzyć odpowiednie ścieżki do drugiego pliku na podstawie jego wiedzy o strukturze pliku zip.

dimpol
źródło
3
Może to lepiej nadawać się do przepełnienia stosu. Sprawdź te pytania: stackoverflow.com/questions/4774054/... stackoverflow.com/questions/59895/... .
Setos II
1
użyć jak. proszę wyjaśnić
Sergiy Kolodyazhnyy
1
@SethosII to pytanie jest całkowicie na ten temat tutaj
Zanna
1
Dodałem więcej kontekstu do pytania. Myślałem, że może istnieć łatwe / oczywiste polecenie, aby uzyskać ścieżkę do pliku, który jest wykonywany, ale wydaje się, że odpowiedź jest co najmniej nieoczywista.
dimpol
3
@Zanna Nie mówię, że to nie na temat, myślę, że jest to po prostu bardziej odpowiednie i jak pokazano z linkami już zadawanymi i odpowiadającymi tam wiele razy.
Setos II

Odpowiedzi:

24

Możesz uzyskać pełną ścieżkę, taką jak:

realpath "$0"

I jak wskazał Serg , możesz użyć dirnamedo usunięcia nazwy pliku w ten sposób

dirname "$(realpath $0)"

lub nawet lepiej, aby uniknąć niezręcznego cytowania i dzielenia słów przy trudnych nazwach plików:

temp=$( realpath "$0"  ) && dirname "$temp"

O wiele lepszy niż mój wcześniejszy pomysł, który polegał na jego analizie (wiedziałem, że będzie lepszy sposób!)

realpath "$0" | sed 's|\(.*\)/.*|\1|'

Notatki

  • realpath zwraca rzeczywistą ścieżkę do pliku
  • $0 to ten plik (skrypt)
  • s|old|new|wymienić oldznew
  • \(.*\)/zachowaj dowolne postacie wcześniej /na później
  • \1 zapisana część
Zanna
źródło
2
+1 za użycie $0i sedmagię. Ale ta sedmagia jest naprawdę niepotrzebna, gdy dirnameistnieją takie narzędzia
Sergiy Kolodyazhnyy
2
masz już odpowiedź, użyj realpath: realpath "$( dirname $0 )"osobiście skorzystałbym, readlinkale to ja:readlink -e $(dirname $0)
Sergiy Kolodyazhnyy
@Serg: Nie dirname "$(realpath "$0")"byłoby lepiej? Zwykle chce się znać katalog nadrzędny odnośnego pliku zamiast katalogu nadrzędnego dowiązania symbolicznego odnoszącego się do tego pliku.
David Foerster,
4
@Serg "$(dirname "$(realpath "$0")")"to najprostszy sposób. Cytaty w środku $()działają normalnie.
Depressed
@DepressedDaniel Przeprowadziłem trochę badań w Internecie, masz rację: $()bycie podpowłoką pozwoli mieć cytaty na zewnątrz. Nie powiedziałbym jednak, że jest to tak proste, chyba że się zorientuje, że $()wszystkie są
otoczkami
5

jeśli skrypt znajduje się na twojej ścieżce, możesz użyć czegoś takiego

$ myloc=$(dirname "$(which foo.sh)")
$ echo "$myloc"
/path/to/foo.sh

EDYCJA: po przeczytaniu komentarzy Serga może to być ogólne rozwiązanie, które działa niezależnie od tego, czy skrypt jest na twojej ścieżce, czy nie.

myloc==$(dirname "$(realpath $0)")
dirname "$myloc"
Antonello Piemonte
źródło
whichjest bardziej odpowiedni, gdy skrypt znajduje się w jednym z katalogów, które są częścią PATHzmiennej. Używaj $0z poziomu skryptu, tak jak pokazuje Zanna. Ale twoja odpowiedź jest właściwa, ponieważ używasz dirnamezamiast sed
zadzierać
5

Przyjęta odpowiedź wydaje się idealna. Oto inny sposób, aby to zrobić:

cd "$(dirname "$0")"
/bin/pwd

/bin/pwdwypisuje prawdziwą ścieżkę do katalogu, w przeciwieństwie do pwdwbudowanego polecenia.

serv-inc
źródło
0
wdir="$PWD"; [ "$PWD" = "/" ] && wdir=""
case "$0" in
  /*) scriptdir="${0}";;
  *) scriptdir="$wdir/${0#./}";;
esac
scriptdir="${scriptdir%/*}"
echo "$scriptdir"

Jest pobierany jako odniesienie od kenorb i andro
Bez nazwy katalogu, readlink, realpath, BASH_SOURCE
Wszystkie są wbudowane

Hemanth Dżabalpuri
źródło