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


35

Spotkałem się BASEDIR=$(pwd)w skrypcie.

Czy są jakieś zalety lub wady w stosunku do używania BASEDIR="$PWD", które $PWDmogą być nadpisane?



@ StéphaneChazelas Bardzo interesujące napisanie. Jestem dopiero w połowie i będę kontynuować, ale o ile rozumiem, lepiej jest używać $(pwd), ponieważ $PWDw niektórych okolicznościach może stać się nieaktualny.
Minix,

2
tylko w niektórych powłokach (na przykład nie bash, dash, zsh lub ksh93) pwdpotencjalnie da ci mniej przestarzałych informacji niż $PWDw niektórych przypadkach narożnych. $(pwd)z drugiej strony nie działa, jeśli bieżący katalog kończy się znakami nowej linii, oznacza rozwidlenie procesu (z wyjątkiem ksh93) i użycie dodatkowych zasobów. Mój pogląd jest stosowanie $PWDod $(pwd -P), to nie warto korzystać $(pwd).
Stéphane Chazelas,

1
na dole stephane wspomina o użyciu cd -P -- "$dir". jeśli masz jakiekolwiek wątpliwości co do wartości $PWD, zawsze możesz cd -P .najpierw. może to być również korzystne, ponieważ dostajesz to, co $PWDbyło wcześniej, $OLDPWDi możesz je później porównać - a następna cd ...; cd -sekwencja z pewnością zaprowadzi cię z powrotem do miejsca, w którym jesteś teraz.
mikeserv

Odpowiedzi:


41

Jeśli bash się napotka $(pwd), wykona polecenie pwd i zastąpi $(pwd)wyjściem tego polecenia. $PWDjest zmienną, która prawie zawsze jest ustawiona. pwd to wbudowane polecenie powłoki od dłuższego czasu.

Tak $PWDsię nie powiedzie, jeśli ta zmienna nie jest ustawiona i $(pwd)zawiedzie, jeśli używasz powłoki, która nie obsługuje $()konstrukcji, co według mnie dość często zdarza się. Więc skorzystałbym $PWD.

Jak każdy nerd mam własny samouczek dotyczący skryptowania powłoki


6
Miałem wrażenie, że `command`składnia jest niepożądana i $(command)należy ją preferować. O ile wiem, ten ostatni jest zgodny z POSIX, ale nie jestem w 100% pewien.
Minix,

6
@Minix $()Rzeczywiście jest to określone przez POSIX, więc poza wcześniejszym POSIXem /bin/shdostępnym na Solarisie 10 i starszych i cshpochodnych powłokach, wątpię, aby wiele innych popularnych powłok nie posiadało tej funkcji.
jlliagre

@Minix: Oto ostatnie pytanie na tej stronie, które ilustruje jeden problem z używaniem backticks zamiast$()
PM 2Ring

poprawne, zamiast $ () można było użyć backticków, ale nie będzie to możliwe kaskadowo, więc nie wspomniałem o tym
Thorsten Staerk

1
Fajna minimapa na twoim tutorialu ....
kbtzr

6

Należy również wspomnieć, że $PWDjest to pożądane ze względu na jego wydajność. Jako zmienna powłoki może być rozwiązana niemal natychmiast. $(pwd)jest nieco bardziej mylące. Jeśli przeprowadzisz inspekcję man 1 bulitinw systemie za pomocą Bash, zobaczysz, że pwdjest to wbudowane polecenie, które może prowadzić do przekonania, że ​​będzie ono równie szybkie, jak dostęp do zmiennej. Jednak $()konstrukcja zawsze uruchamia nową podpowłokę (nowy proces) w celu uruchomienia jej zawartości, niezależnie od tego, co jest w środku. To samo dotyczy backticks. Rzeczywiście, kiedy go porównuję:

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 $(pwd)połączenie i 0,018 sekundy na $PWD. W miarę możliwości należy unikać niepotrzebnego uruchamiania podpowłoki, a także wszelkich innych procesów zewnętrznych. Są znacznie droższe niż wywołania funkcji, do których możesz być przyzwyczajony w innych językach.


To ciekawe podejście, ale nie wiem, czy martwię się wydajnością moich skryptów powłoki. Zastanawiam się również, jak zmieniłaby się wydajność, gdyby pwd zmieniał się między zapytaniami.
Minix,

@Minix Zmodyfikowałem skrypt tak, aby ciało pętli było echo $PWD; pushd ..; echo $PWD; popd(z dodatkowymi >/dev/nullpo każdej instrukcji), i zajmuje to 0,05 sekundy. Następnie usunąłem instrukcje echa (tylko pushd / popd) i zajęło to 0,03. Tak więc czas na echo $PWDnadal wynosił około 0,01 sekundy. Zrobiłem coś podobnego $(pwd)i zajęło to 2,2 sekundy dla każdej pętli, więc 1,1 sekundy na $(pwd)połączenie.
markasoftware

Nie jestem zbyt wybredny, ale mogę sobie wyobrazić, że obliczenia, które zastąpiłyby, $PWDzostałyby wykonane w tle przed oceną instrukcji echa. Ale najwyraźniej dostęp $PWDjest wciąż znacznie szybszy, więc jeśli kompatybilność nie stanowi problemu, jest to zdecydowanie powód, aby wybierać między sobą. Dziękujemy za pracę nad tak dokładnym testowaniem. :)
Minix,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.