Piszę skrypt bash. Potrzebuję bieżącego katalogu roboczego, aby zawsze był katalogiem, w którym znajduje się skrypt.
Domyślne zachowanie polega na tym, że bieżącym katalogiem roboczym skryptu jest powłoka, z której go uruchamiam, ale nie chcę tego zachowania.
myscript path/to/file
, oczekuję, że skrypt oceni ścieżkę / do / pliku względem MOJEGO bieżącego katalogu, a nie tego, który katalog się wydarzy do znalezienia się. Co by się stało z uruchomieniem skryptu,ssh remotehost bash < ./myscript
jak wspomniano w BASH FAQ?cd "${BASH_SOURCE%/*}" || exit
Odpowiedzi:
źródło
$0
. W skrypcie można oczekiwać na przykład,../../
że odniesie się do katalogu dwa poziomy powyżej lokalizacji skryptu, ale niekoniecznie dzieje się tak, jeśli w grę wchodzą dowiązania symboliczne../script
,.
to jest to poprawny katalog, a przejście do.
niego skończy się również w samym katalogu, w którym sięscript
znajduje, tj. W bieżącym katalogu roboczym.bash script.sh
, wówczas wartość$0
toscript.sh
. Jedynym sposobem, w jakicd
polecenie będzie dla ciebie „działało”, jest to, że nie przejmujesz się nieudanymi poleceniami. Jeśli miałbyś użyćset -o errexit
(aka:)set -e
aby upewnić się, że twój skrypt nie wysadzi nieudanych poleceń, NIE zadziałałobycd script.sh
to, ponieważ jest to błąd. Wiarygodnym sposobem [bash] jestcd "$(dirname ${BASH_SOURCE[0]})"
Działa również:
Składnia została dokładnie opisana w tej odpowiedzi StackOverflow.
źródło
bash script.sh
-$0
będzie to po prostu nazwa plikuWypróbuj następujące proste jednolinijki:
Dla wszystkich systemów UNIX / OSX / Linux
Grzmotnąć
Uwaga: Podwójny myślnik (-) jest używany w poleceniach do oznaczenia końca opcji poleceń, więc pliki zawierające myślniki lub inne znaki specjalne nie spowodują złamania polecenia.
Uwaga: w Bash użyj
${BASH_SOURCE[0]}
na korzyść$0
, w przeciwnym razie ścieżka może się złamać podczas jej pozyskiwania (source
/.
).W przypadku systemu Linux, Mac i innych * BSD:
Uwaga:
realpath
powinien być domyślnie zainstalowany w najpopularniejszej dystrybucji Linuksa (np. Ubuntu), ale w niektórych może go brakować, więc musisz go zainstalować.Uwaga: Jeśli używasz Bash, użyj
${BASH_SOURCE[0]}
na korzyść$0
, w przeciwnym razie ścieżka może się złamać podczas jej pozyskiwania (source
/.
).W przeciwnym razie możesz spróbować czegoś takiego (użyje pierwszego istniejącego narzędzia):
W przypadku systemu Linux:
Używając linku do odczytu GNU na * BSD / Mac:
Uwaga: Musisz mieć
coreutils
zainstalowany (np. 1. Zainstaluj Homebrew , 2.brew install coreutils
).W bash
W bash możesz użyć do tego celu rozszerzeń parametrów , takich jak:
ale to nie działa, jeśli skrypt jest uruchamiany z tego samego katalogu.
Alternatywnie możesz zdefiniować następującą funkcję w bash:
Ta funkcja przyjmuje 1 argument. Jeśli argument ma już ścieżkę bezwzględną, wypisz ją taką, jaka jest, w przeciwnym razie wypisz
$PWD
argument zmienna + nazwa pliku (bez./
prefiksu).lub tutaj jest wersja zaczerpnięta z
.bashrc
pliku Debian :Związane z:
Jak wykryć bieżący katalog, w którym uruchamiam skrypt powłoki?
Pobierz katalog źródłowy skryptu Bash z poziomu samego skryptu
Bezwzględna ścieżka skryptu Bash w systemie OS X
Niezawodny sposób, aby skrypt Bash uzyskał pełną ścieżkę do siebie
Zobacz też:
Jak mogę uzyskać zachowanie readlink -f GNU na komputerze Mac?
źródło
cp
poleceniu, @kenorb?--
) jest używana w poleceniach do oznaczenia końca opcji polecenia, więc pliki zawierające myślniki lub inne znaki specjalne nie spowodują złamania polecenia. Spróbuj np. Utworzyć plik za pomocątouch "-test"
itouch -- -test
, a następnie usuń plik za pomocąrm "-test"
irm -- -test
i zobacz różnicę.realpath
pakiet Debiana jest przestarzały, a nie GNUrealpath
. Jeśli uważasz, że to nie jest jasne, możesz zasugerować edycję.To jest łatwe. To działa.
źródło
cd "${BASH_SOURCE%/*}" || exit
Akceptowana odpowiedź działa dobrze dla skryptów, które nie zostały dowiązane symbolicznie w innym miejscu, na przykład do
$PATH
.Jeśli jednak skrypt jest uruchamiany za pomocą dowiązania symbolicznego,
Spowoduje to przejście do
~/bin/
katalogu, a nie do~/project/
katalogu, co prawdopodobnie spowoduje uszkodzenie skryptu, jeśli celemcd
jest uwzględnienie zależności względem~/project/
Bezpieczna odpowiedź dowiązania symbolicznego znajduje się poniżej:
readlink -f
jest wymagane do rozwiązania ścieżki bezwzględnej potencjalnie dowiązanego pliku.Cudzysłowy są wymagane do obsługi ścieżek plików, które potencjalnie mogą zawierać spacje (zła praktyka, ale nie jest bezpiecznie zakładać, że tak nie będzie)
źródło
Ten skrypt wydaje mi się działać:
Wiersz polecenia pwd przypomina lokalizację skryptu jako bieżącego katalogu roboczego, bez względu na to, skąd go uruchamiam.
źródło
realpath
prawdopodobnie nie zostanie zainstalowany wszędzie. Co może nie mieć znaczenia, w zależności od sytuacji PO.realpath
ale ma taki,readlink
który wydaje się podobny.Uzyskaj prawdziwą ścieżkę do skryptu
(To jest odpowiedź na to samo moje pytanie tutaj: Uzyskaj nazwę katalogu, w którym skrypt jest wykonywany )
źródło
źródło
PWD jest zmienną środowiskową.
źródło
Jeśli potrzebujesz tylko wydrukować obecny katalog roboczy, możesz to zrobić.
Udziel pozwolenia na wykonanie:
Następnie uruchom skrypt
./test
, aby zobaczyć aktualny katalog roboczy.źródło
pwd
? Wydaje mi się, że wiele zmarnowanych naciśnięć klawiszy.