Jaka jest różnica między $ (polecenie) a `polecenie` w programowaniu powłoki?


258

Aby zapisać wynik polecenia jako zmienną w sh / ksh / bash, możesz zrobić jedno z nich

var=$(command)

lub

var=`command`

Jaka jest różnica między tymi dwiema metodami?


29
Proszę zobaczyć BashFAQ / 082 .
Wstrzymano do odwołania.

Zagnieżdżony problem znajdziesz szczegółowo w wytycznych Git Coding Guideline: patrz moja odpowiedź poniżej .
VonC,

Odpowiedzi:


274

Znaki wsteczne / znaki grawitacyjne zostały wycofane na korzyść $()zastępowania poleceń, ponieważ $()mogą łatwo zagnieżdżać się w sobie jak w $(echo foo$(echo bar)). Istnieją inne różnice, takie jak sposób analizowania ukośników odwrotnych w wersji backtick / gravemark itp.

Zobacz BashFAQ / 082 z kilku powodów, aby zawsze preferować składnię $ (...).

Zobacz także specyfikację POSIX, aby uzyskać szczegółowe informacje na temat różnych różnic.


25
Dobre połączenie, ale tekst nie potępiać odwrotnego cudzysłowiu rzecz $(...)- po prostu zauważa je jako alternatywy.
Norman Gray

24
@NormanGray POSIX może nie powiedzieć słowa przestarzałe, ale mówi, "the backquoted variety of command substitution is not recommended"co jest po prostu
odrętwiałym

11
POSIX nie przestarzał backticks, ale raczej dodano $(...)jako alternatywną metodę. Nie ma znanego błędu implementacji z backtickami, ale istnieje wiele znanych błędów implementacji z $(...) . Dlatego w przypadku problemów związanych z przenośnością zaleca się stosowanie tylnych zwrotów w przypadku zagnieżdżonych połączeń. $(...)wymaga parsera rekurencyjnego, ale nie został on użyty w ksh86, który wprowadził tę funkcję. Sprawdź inulm.de/~mascheck/various/cmd-subst, aby uzyskać listę poprawnych implementacji. Powłoka zgodna musi obsługiwać wszystkie przypadki z wyjątkiem sprawy D.2.
schily

2
W POSIX są inne rzeczy, które należy postrzegać jako deprecated, np. Użycie waitpid()tego uniemożliwia dostrzeżenie pełnych 32 bitów z exit()parametru, ale wszystkie powłoki z wyjątkiem ostatniej powłoki Bourne'a nadal używają waitpid()zamiast waitid()wywołania, które jest teraz dostępne od 26 lat
schily

Link w odpowiedzi wskazuje, że istnieją pewne różnice między backtickami i $()co jest bardziej wyjaśnione w tej części dokumentacji . Różnice dotyczą nie tylko zagnieżdżenia.
Jakiś programista koleś

39

Zachowują się tak samo. Różnica jest składniowa: łatwiej jest zagnieździć $()niż ``:

listing=$(ls -l $(cat filenames.txt))

vs.

listing=`ls -l \`cat filenames.txt\``

10
echo $(echo \$abc)to nie to samo, co echo `echo \$abc`‍- Różnice istnieją również dla $(echo \`)i $(echo \\)
Peter.O

Inną różnicą jest to: echo foo `#comment`vs echo foo $(#comment). Drugi nie działa. (Używane do komentowania w poleceniu wieloliniowym.)
wisbucky,

27

Lipiec 2014: Zatwierdzenie f25f5e6 (autor: Elia Pinto ( devzero2000) , kwiecień 2014, Git 2.0) dodaje do problemu zagnieżdżania:

Postać w cudzysłowie jest tradycyjną metodą zastępowania poleceń i jest obsługiwana przez POSIX.
Jednak wszystkie zastosowania oprócz najprostszych szybko się komplikują.
W szczególności wbudowane podstawienia poleceń i / lub stosowanie podwójnych cudzysłowów wymagają ostrożnego ucieczki ze znakiem odwrotnego ukośnika
.

Właśnie dlatego git / Documentation / CodingGuidelines wspomina:

Preferujemy $( ... )zastępowanie poleceń; w przeciwieństwie do ``, poprawnie się zagnieżdża .
Powinno tak wyglądać Bourne od pierwszego dnia, ale niestety tak nie jest.

Thiton skomentował :

To dlatego `echo `foo`` nie działa w ogóle z powodu wewnętrznej dwuznaczności, ponieważ każda z nich ``może się otwierać lub zamykać.
Może to działać w szczególnych przypadkach z powodu szczęścia lub specjalnych funkcji.


Aktualizacja styczeń 2016: Git 2.8 (marzec 2016) całkowicie pozbywa się backticksa.

Zobacz popełnić ec1b763 , popełnić 9c10377 , popełnić c7b793a , popełnić 80a6b3f , popełnić 9375dcf , popełnić e74ef60 , popełnić 27fe43e , popełnić 2525c51 , popełnić becd67f , popełnić a5c98ac , popełnić 8c311f9 , popełnić 57da049 , popełnić 1d9e86f , popełnić 78ba28d , popełnić efa639f , popełnić 1be2fa0 , zobowiązać 38e9476 , zatwierdzenie 8823d2f , zatwierdzenie 32858a0 , zatwierdzenie cd914d8(12 stycznia 2016) autor: Elia Pinto ( devzero2000) .
(Połączone przez Junio ​​C Hamano - gitster- w commit e572fef , 22 stycznia 2016)

Począwszy od Gita 2.8, to już wszystko $(...), nic więcej `...`.


2
$()jest również określony przez POSIX - cytat opisujący backtyki jako „wspierane przez POSIX” w taki sposób, aby sugerować, że jest to dla nich unikalne, jest mylący. Jest to jedyna (era 1970) wersja sprzed POSIX Bourne, gdzie jedyną obsługiwaną składnią są backtyki.
Charles Duffy

25

Gdy używana jest starsza forma tykania, odwrotny ukośnik zachowuje swoje dosłowne znaczenie, chyba że po nim następuje $, `lub \. Pierwszy tyknięcie poprzedzone odwrotnym ukośnikiem kończy podstawianie poleceń.

Podczas korzystania z nowszej $(command)formy wszystkie znaki między nawiasami tworzą polecenie; żaden nie jest traktowany specjalnie.

Obie formy można zagnieżdżać, ale odmiana zaznaczania wstecznego wymaga następującej formy.

`echo \`foo\`` 

W przeciwieństwie do:

$(echo $(foo))

1
Niewielka korekta, zarówno wersja wsteczna, jak i $()wersja są zgodne z POSIX.
SiegeX

5

Różnica jest niewielka, z wyjątkiem tego, jakich nieskalowanych znaków możesz użyć wewnątrz polecenia. Możesz nawet umieścić polecenia „...” wewnątrz poleceń $ (...) (i odwrotnie), aby uzyskać bardziej skomplikowane podstawianie poleceń na dwóch poziomach.

Istnieje nieco inna interpretacja znaku / operatora odwrotnego ukośnika. Między innymi, zagnieżdżając polecenia podstawienia `...` , musisz uciec wewnętrznymi znakami `za pomocą \, podczas gdy w przypadku podstacji $ () automatycznie rozpoznaje zagnieżdżanie.


0

„Jaka jest różnica między tymi dwiema metodami?”

Zwróć uwagę na to zachowanie:

A="A_VARIABLE"
echo "$(echo "\$A")"
echo "`echo "\$A"`"

Otrzymasz te wyniki:

$A
A_VARIABLE

 

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.