Czy lepiej jest użyć $ (pwd) czy $ PWD?

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 najpierw cd -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ępnie cd ...; 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

  • Odniosłem wrażenie, że składnia `command` jest niepożądana i $(command) należy preferować. O ile wiem, ten ostatni jest zgodny z POSIX, ale ' nie jestem w 100% pewien.
  • @Minix $() jest rzeczywiście określony przez POSIX, więc poza /bin/sh pre-POSIX dostępnym w systemie Solaris 10 i starszych oraz csh powłokach pochodnych, wątpię w wiele inne główne powłoki nie mają tej funkcji.
  • @Minix: Tutaj jest niedawne pytanie w tej witrynie, które ilustruje jeden problem z używaniem znaków odwrotnych zamiast $()
  • dobrze, zamiast $ () można użyć grawitacji, ale nie będzie to możliwe do kaskadowania, więc nie wspomniałem o tym
  • Niezła minimapa w twoim samouczku ….

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 na echo $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. 🙂

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *