В чем разница между $(command) и `command` в программировании оболочки?

Чтобы сохранить вывод команды как переменную в sh/ksh/bash, вы можете сделать

var=$(command)

или же

var=`command`

Какая разница, если таковые имеются между двумя методами?

7 ответов

Решение

Бэктикс / могильные знаки устарели в пользу $() для замены команды, потому что $() может легко вложиться в себя, как в $(echo foo$(echo bar)), Существуют и другие различия, такие как анализ обратной косой черты в версии backtick /gravemark и т. Д.

См. BashFAQ / 082 по нескольким причинам, чтобы всегда отдавать предпочтение синтаксису $(...).

Также см. Спецификацию POSIX для получения подробной информации о различных различиях.

Они ведут себя одинаково. Разница синтаксическая: гнездиться легче $() чем ``:

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

против

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

Июль 2014: коммит f25f5e6 (автор Elia Pinto ( devzero2000 ), Апрель 2014 г., Git 2.0) добавляет к вопросу вложенности:

Форма в кавычках является традиционным методом подстановки команд и поддерживается POSIX.
Тем не менее, все, кроме простейшего использования быстро усложняются.
В частности, встроенные подстановки команд и / или использование двойных кавычек требуют осторожного экранирования с символом обратной косой черты.

Вот почему Git/Documentation/CodingGuidelines упоминает:

Мы предпочитаем $( ... ) для подстановки команд; в отличие от ``, он правильно вложен.
Это должен был быть способ, которым Борн написал это с первого дня, но, к сожалению, это не так.

thiton прокомментировал:

Поэтому `echo `foo`` не будет работать вообще из-за присущей неоднозначности, потому что каждый `` может быть открытием или закрытием.
Это может работать для особых случаев из-за удачи или специальных функций.


Обновление от января 2016 года: Git 2.8 (март 2016 года) полностью избавился от недостатков.

См. Коммит ec1b763, коммит 9c10377, коммит c7b793a, коммит 80a6b3f, коммит 9375dcf, коммит e74ef60, коммит 27fe43e, коммит 2525c51, коммит becd67f, коммит a5c98ac, коммит 8c311f9, коммит 57da049, коммит 1d9e86f, коммит 1b6394d, коммит 78ba28d 38e9476, коммит 8823d2f, коммит 32858a0, коммит cd914d8 (12 января 2016 г.) Элия ​​Пинто ( devzero2000 )
(Объединено Юнио С Хамано - gitster - в коммите e572fef, 22 января 2016 г.)

Начиная с Git 2.8, это все $(...), больше не надо `...`,

Когда используется более старая форма обратной галочки, обратная косая черта сохраняет свое буквальное значение, за исключением случаев, когда следуют $, `или \. Первая обратная галочка, которой не предшествует обратная косая черта, завершает подстановку команды.

При использовании более нового $(command) форма, все символы в скобках составляют команду; никто не лечится специально.

Обе формы могут быть вложенными, но разновидность обратного тика требует следующую форму.

`echo \`foo\`` 

В отличие от:

$(echo $(foo))

Существует небольшая разница, за исключением того, какие символы без экранирования вы можете использовать внутри команды. Вы можете даже поместить команды `...` внутри $(...) (и наоборот) для более сложной двухуровневой подстановки команд.

Существует немного другая интерпретация символа / оператора обратной косой черты. Помимо прочего, при вложении команд подстановки `...` вы должны экранировать внутренние символы ` с помощью \, тогда как при подстановке $() он автоматически распознает вложенность.

"Какая разница, если таковые имеются между двумя методами?"

Обратите внимание на это поведение:

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

Вы получите эти результаты:

$A
A_VARIABLE

Одно новое различие между обратными кавычками и более новым предпочтительным синтаксисом POSIX для подстановки команд заключается в том, как обрабатываются комментарии. Символ решетки внутри обратных кавычек создает комментарий, который заканчивается на втором символе обратной кавычки, что фактически дает возможность иметь комментарии в средней строке.

      $ echo "Goodbye` # Cruel` World"
Goodbye World

При использовании более нового предпочтительного синтаксиса комментарий продолжается до конца строки, поэтому команду придется разделить на две строки:

      $ echo "Goodbye$( # Cruel
> ) World"
Goodbye World

Если вы попытаетесь ввести его в консоль в одной строке, ваш терминал просто перенесет:

      $ echo "Goodbye$( # Cruel) World"
> 

Но вы можете перевести его в одну строку, передав командуsh -c. Затем вы увидите, что это приводит к синтаксической ошибке:

      $ sh -c 'echo "Goodbye$( # Cruel) World"'
sh: 1: Syntax error: end of file unexpected (expecting ")")
Другие вопросы по тегам