В чем разница между $ (вещи) и `вещи`?

265

Есть два синтаксиса для подстановки команд: с долларовыми скобками и с обратными галочками. Работает top -p $(pidof init)и top -p `pidof init`выдает тот же вывод. Это два способа сделать одно и то же или есть различия?

tshepang
источник
18
Смотрите также: BashFAQ / 082 .
Деннис Уильямсон
43
На секунду я подумал, что это вопрос jQuery.
Дэвид Мердок
Результат может зависеть от оболочки - некоторые поддерживают оба.
Артданил

Ответы:

360

Обратные кавычки старого стиля ` `обрабатывают обратную косую черту и вложенность немного по-другому. Новый стиль $()интерпретирует все промежуточное ( )как команду.

echo $(uname | $(echo cat))
Linux

echo `uname | `echo cat``
bash: command substitution: line 2: syntax error: unexpected end of file
echo cat

работает, если вложенные обратные кавычки экранированы:

echo `uname | \`echo cat\``
Linux

удовольствие от обратной косой черты:

echo $(echo '\\')
\\

echo `echo '\\'`
\

Новый стиль $()применяется ко всем POSIX-совместимым оболочкам.
Как указывал Мувичиэль , старый стиль ` `может быть необходим для более старых оболочек.

Помимо технической точки зрения, старый стиль ` `имеет и визуальный недостаток:

  • Трудно заметить: I like $(program) better than `program`
  • Легко путать с одной цитатой: '`'`''`''`'`''`'
  • Не так просто печатать (возможно даже не на стандартной раскладке клавиатуры)

(и SE использует ` `в своих целях, было очень тяжело писать этот ответ :)

шутник
источник
10
Единственное , что я хотел бы добавить, что я называю «(» а скобка, а не кронштейн (который является «[»).
Кендалл Helmstetter Gelner
@Kendall: и здесь я подумал, что '{' был левой скобкой для всех этих лет ...
SamB
5
@Sam: { }обычно называют «фигурными скобками» или «фигурными скобками» en.wikipedia.org/wiki/Braces_(punctuation)#Braces
Jørn Schou-Rode
2
Я также называю '{' фигурными скобками. Хотя это кажется странным, вам нужно добавить классификатор «curly», если вы называете другие скобки ... Я думаю, это только потому, что они на самом деле скручиваются.
Кендалл Хельмштеттер Гелнер
1
@slim Я не знаю, на клавиатурах США / Великобритании, но на испанских клавиатурах `это мертвая клавиша, поэтому я должен набрать либо двойной обратный удар (что я обычно забываю, я даже могу сделать), либо обратный удар после пробела, который является боль.
Darkhogg
41

Очевидное различие, которое я наблюдаю, состоит в том, что вы не можете вкладывать обратные метки, в то время как можете вкладывать $(). Возможно, оба существуют по наследственным причинам. Точно так же .и sourceкоманды являются синонимами.

Балки
источник
10
Некоторые раковины, полученные из Борна, не распознают source. Тире является одним из примеров.
Деннис Уильямсон
14
Это не правда. Вы можете вкладывать backtick на любой уровень, только более болезненно. Обратите внимание, что оба $(...)и `...`являются стандартными (последний является устаревшим), в то время как .является стандартным, но нетsource
Стефан Шазелас
3
Исправление, только в том, что (t)cshони не могут быть вложенными. (t)cshне поддерживаю $(...)все же Они поддерживают source(и не .), хотя.
Стефан Шазелас
28

$()не работает со старой оболочкой Bourne. Но прошло много лет, как я работал со старой оболочкой Bourne.

mouviciel
источник
Старый как в 1970-х и начале 1980-х, верно?
Кристофер
6

Еще одно примечание, $()будет использовать больше системных ресурсов, чем использование обратных галочек, но немного быстрее.

В разделе « Освоение сценариев оболочки Unix» Рэндал К. Майкл провел тест в главе под названием «24 способа обработки файла построчно».

cuonglm
источник
2
Это утверждение ерунда. Нет никаких причин, почему это должно быть быстрее, поскольку это просто использование другой записи для синтаксического анализатора.
Щил
@schily: Может быть, я только цитирую из книги, вы можете прочитать ее для более подробной информации.
cuonglm
3
Я склонен согласиться с @schily ... с чего бы это потребовало больше ресурсов?
Уайлдкарт
2
@Wildcard, я полагаю, это потому, что $()делает ваш скрипт на один байт больше, чем если бы он использовал `(при условии, что вы их не вкладываете и не используете обратную косую черту внутри). Что из того, что будет быстрее анализировать, будет варьироваться между оболочками и не будет иметь значения, так как незначительно по сравнению со стоимостью создания канала и разветвления процесса, что влечет за собой замену команды.
Стефан Шазелас
5

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

echo foo `# I'm a comment!` bar

Выход: foo bar.

Для получения дополнительной информации см. Следующее: https://stackoverflow.com/a/12797512 (обратите внимание также на комментарии под этим сообщением.)

PHK
источник
1

$()Синтаксис не будет работать со старой оболочкой Борна.
С новыми оболочками ` `и $()эквивалентны, но $()гораздо удобнее использовать, когда вам нужно вложить несколько команд.

Например :

echo $(basename $(dirname $(dirname /var/adm/sw/save )))

легче набрать и отладить, чем:

echo `basename \`dirname \\\`dirname /var/adm/sw/save \\\`\``
Эммануэль
источник
1
Хотя $ () может выглядеть хорошо, но при реализации связанного синтаксического анализатора возникает боль, потому что он требует двойного рекурсивного синтаксического анализатора.
Щил
6
@schily С другой стороны, что бы это была оболочка без хорошего парсера.
Эммануэль
1
Проблема в том, что вам нужно знать, где заканчивается строка, прежде чем вызывать анализатор. С обратными галочками это относительно просто, но с квадратными скобками сложно, так как они используются для различных целей в оболочке. Таким образом, вам нужен парсер дважды и таким образом, которого нет в Bourne Shell.
Щили