Napotkałem BASEDIR=$(pwd)
w skrypcie.
Czy są jakieś zalety lub wady w stosunku do używając BASEDIR="$PWD"
, z wyjątkiem być może, że $PWD
można nadpisać?
Komentarze
- trochę informacji pod adresem unix.stackexchange.com/a/79621
- @St é phaneChazelas Bardzo interesujący opis. ' m tylko w połowie i będę kontynuować, ale o ile to zrozumiałem, ' lepiej jest użyć
$(pwd)
, ponieważ$PWD
może stać się nieaktualny w pewnych okolicznościach. - tylko w niektórych powłokach (nie bash, dash, zsh lub ksh93 dla instancja)
pwd
potencjalnie daje mniej przestarzałych informacji niż$PWD
w niektórych przypadkach narożnych.$(pwd)
z drugiej strony nie ' t działa, jeśli bieżący katalog kończy się znakami nowej linii, oznacza rozwidlenie procesu (z wyjątkiem ksh93) i użyj dodatkowych zasobów. Mój pogląd jest następujący:$PWD
z$(pwd -P)
, to ' nie warto używać$(pwd)
. - na dole stephane wspomina o użyciu
cd -P -- "$dir"
. jeśli masz jakiekolwiek wątpliwości co do wartości$PWD
, możesz zawsze najpierwcd -P .
. może to być również korzystne, ponieważ w$OLDPWD
otrzymasz również wszystko, co$PWD
było wcześniej niż w$OLDPWD
, dzięki czemu możesz je później porównać – a następniecd ...; cd -
z pewnością przeniesie Cię z powrotem do miejsca, w którym jesteś teraz.
Odpowiedź
Jeśli bash napotka $(pwd)
, wykona polecenie pwd i zamieni $(pwd)
na wyjście tego polecenia. $PWD
to zmienna, która jest prawie zawsze ustawiona. pwd to wbudowane polecenie powłoki od dawna.
Więc $PWD
zakończy się niepowodzeniem, jeśli ta zmienna nie zostanie ustawiona, a $(pwd)
zakończy się niepowodzeniem, jeśli używasz powłoki, która nie obsługuje konstrukcji $()
, która ma z mojego doświadczenia często się zdarza. Dlatego użyłbym $PWD
.
Jak każdy nerd mam swój własny samouczek dotyczący skryptów powłoki
Comme nts
Odpowiedź
Należy również wspomnieć, że jest pożądane ze względu na jego wydajność. Jako zmienna powłoki można ją rozwiązać niemal natychmiast. $(pwd)
jest nieco bardziej zagmatwane. Jeśli sprawdzisz man 1 bulitin
w systemie z Bash, „zobaczysz, że pwd
jest poleceniem wbudowanym, które może prowadzić do wierzę, że będzie to tak samo szybkie, jak uzyskanie dostępu do zmiennej. Jednak konstrukcja $()
zawsze uruchamia nową podpowłokę (nowy proces), aby uruchomić swoją zawartość, niezależnie od tego, co jest w środku . To samo dotyczy grawitów. Rzeczywiście, kiedy wykonuję test porównawczy:
echo "Benchmarking $(pwd)..." time (for i in {1..1000}; do echo $(pwd) > /dev/null; done) echo "Benchmarking $PWD..." time (for i in {1..1000}; do echo $PWD > /dev/null; done)
Dostaję 1,52 sekundy na połączenie $(pwd)
i 0,018 sekundy na $PWD
. W miarę możliwości należy unikać niepotrzebnego uruchamiania podpowłok, a także wszelkich innych zewnętrznych procesów. Są znacznie droższe niż wywołania funkcji, do których możesz być przyzwyczajony w innych językach.
Komentarze
- To ' to ciekawe podejście, ale nie ' nie wiem, czy obawiam się o wydajność moich skryptów powłoki. Zastanawiam się też, jak zmieniłaby się wydajność, gdyby pwd zmienia się między zapytaniami.
- @Minix Zmodyfikowałem mój skrypt tak, aby treść pętli była
echo $PWD; pushd ..; echo $PWD; popd
(z dodatkowym>/dev/null
po każdej instrukcji) i zajmuje to 0,05 s. Następnie usunąłem instrukcje echo (tylko pushd / popd) i zajęło to 0,03.Zatem czas naecho $PWD
nadal wynosił 0,01 sekundy. Zrobiłem coś podobnego z$(pwd)
i każda pętla zajmowała 2,2 sekundy, więc 1,1 sekundy na wywołanie$(pwd)
. - Nie chcę być zbyt wybredny, ale mogę sobie wyobrazić, że obliczenia, które zastąpiłyby
$PWD
, zostałyby wykonane w tle przed oceną instrukcji echo. Ale oczywiście dostęp do$PWD
jest nadal znacznie szybszy, więc jeśli kompatybilność nie jest problemem, jest to zdecydowanie powód, aby wybrać jeden z nich. Dziękuję za tak dokładne przetestowanie tego. 🙂
`command`
jest niepożądana i$(command)
należy preferować. O ile wiem, ten ostatni jest zgodny z POSIX, ale ' nie jestem w 100% pewien.$()
jest rzeczywiście określony przez POSIX, więc poza/bin/sh
pre-POSIX dostępnym w systemie Solaris 10 i starszych orazcsh
powłokach pochodnych, wątpię w wiele inne główne powłoki nie mają tej funkcji.$()