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?
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?
Odpowiedzi:
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.
$(...)
- po prostu zauważa je jako alternatywy.
"the backquoted variety of command substitution is not recommended"
co jest po prostu
$(...)
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.
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
$()
co jest bardziej wyjaśnione w tej części dokumentacji . Różnice dotyczą nie tylko zagnieżdżenia.
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\``
echo $(echo \$abc)
to nie to samo, co echo `echo \$abc`
- Różnice istnieją również dla $(echo \`)
i $(echo \\)
echo foo `#comment`
vs echo foo $(#comment)
. Drugi nie działa. (Używane do komentowania w poleceniu wieloliniowym.)
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.
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 `...`
.
$()
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.
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))
$()
wersja są zgodne z POSIX.
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.