Co to znaczy w powłoce, gdy umieścimy polecenie w znaku dolara i nawiasach: $ (polecenie)

110

Chcę tylko zrozumieć następujący wiersz kodu w powłoce. Służy do pobierania bieżącego katalogu roboczego. Zdaję sobie sprawę, że $(variable)nazwa zwraca wartość wewnątrz nazwy zmiennej, ale co $(command)ma zwrócić? Czy zwraca wartość po wykonaniu polecenia? W takim przypadku możemy użyć `do wykonania polecenia.

CWD="$(cd "$(dirname $0)"; pwd)"

Te same dane wyjściowe można pobrać z następującego wiersza kodu również w innej wersji powłoki

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

Nie jestem w stanie zrozumieć znaczenia $(cd..i $(dirname.

Czy ktoś mógłby mi pomóc dowiedzieć się, jak to polecenie jest wykonywane?

KItis
źródło
1
A oto pytanie o zalety / wady $()vs ``.: stackoverflow.com/questions/9449778/ ...
Brak

Odpowiedzi:

115

Użycie $podobnych ${HOME}daje wartość DOMU. Użycie $podobnych $(echo foo)oznacza uruchomienie wszystkiego, co znajduje się w nawiasach w podpowłoce i zwrócenie tego jako wartości. W moim przykładzie dostaniesz, fooponieważ echonapisze foodo standardu

Eric Urban
źródło
37
Tak; $(...)to lepszy sposób na napisanie polecenia niż próba użycia cudzysłowów. Zastanów się nad napisaniem: gcclib=$(dirname $(dirname $(which gcc)))/libużywając cytatów wstecz. Nawet zanim napotkasz trudności związane z robieniem tego w Markdown, jest to trudniejsze, ponieważ musisz uciec przed cudzysłowami zagnieżdżonych poleceń, podczas gdy nie robisz tego z $(...)notacją.
Jonathan Leffler
7
Technicznie rzecz biorąc, $(echo foo)tworzy substytucję polecenia, a nie podpowłokę. Druga aktualna odpowiedź jest właściwa. Wydaje mi się, że podstawianie poleceń odbywa się w pewnym sensie w podpowłoce, ale nadal są to różne koncepcje.
trysis
4
@trysis - podstawianie poleceń na pewno działa w podpowłoce , dlatego warto to odnotować.
Eliran Malka,
2
Rozumiem, że grawerowanie daje ten sam wynik co $ (), ale czy różnica jest czysto kosmetyczna? czy jest powód, aby używać jednego kontra drugiego, poza tym, że $ () jest bardziej czytelny?
Mitchell Tracy
2
„Użycie znaku $ jak $ (echo foo) oznacza uruchomienie tego, co znajduje się w nawiasach w podpowłoce i zwrócenie tego jako wartości”. ... To jest mylące, ponieważ to polecenie $(echo foo)spróbuje uruchomić to, co jest zwrócone z nawiasów, najpierw uruchomi się, echo fooa następnie spróbuje uruchomić, fooco powoduje błąd
Księgowy م
21
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

Czy ktoś mógłby mi pomóc dowiedzieć się, jak to polecenie jest wykonywane?

Spójrzmy na różne części polecenia. BASH_SOURCEjest zmienną tablicową bash zawierającą nazwy plików źródłowych. Więc "${BASH_SOURCE[0]}"zwróci ci nazwę pliku skryptu.

dirnameto narzędzie dostarczane przez GNU coreutils, które usuwa ostatni komponent z nazwy pliku. Tak więc, jeśli wykonasz skrypt, mówiąc bash foo, "$( dirname "${BASH_SOURCE[0]}" )"zwróci .. Gdybyś powiedział bash ../foo, to wróci ..; bo bash /some/path/foowróci /some/path.

Na koniec całe polecenie "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"pobiera bezwzględny katalog zawierający wywoływany skrypt.

$(...) umożliwia podstawianie poleceń, tj. pozwala wynikowi polecenia zastąpić samo polecenie i może być zagnieżdżony.

devnull
źródło
1
Przepraszam, że spóźniłem się na przyjęcie 3 lata, ale czy mógłbyś wyjaśnić, dlaczego to stwierdzenie działa? Powiedziałeś, że dirnamezwraca ścieżkę wykonywanego pliku (względną lub bezwzględną do obecnego katalogu roboczego), cdzmienia pwd na ten katalog i pwdwypisuje bezwzględną ścieżkę do bieżącego katalogu roboczego. Ale dlaczego do nich dołącza &&? A co się stanie, DIRjeśli cdzawiedzie?
Christian,
2
@Christian, &&uniemożliwia pwduruchomienie programu w przypadku cdniepowodzenia, co DIRspowoduje, że będzie on pusty zamiast mieć niepoprawny katalog.
Charles Duffy,