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


265

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


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.


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

6

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

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


2
Это утверждение ерунда. Нет никаких причин, почему это должно быть быстрее, поскольку это просто использование другой записи для синтаксического анализатора.
— Щил

@schily: Может быть, я только цитирую из книги, вы можете прочитать ее для более подробной информации.
— cuonglm

3
Я склонен согласиться с @schily ... с чего бы это потребовало больше ресурсов?
— Уайлдкарт

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

5

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

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

Выход: foo bar.

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


1

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

Например :

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

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

echo `basename \`dirname \\\`dirname /var/adm/sw/save \\\`\``

1
Хотя $ () может выглядеть хорошо, но при реализации связанного синтаксического анализатора возникает боль, потому что он требует двойного рекурсивного синтаксического анализатора.
— Щил

6
@schily С другой стороны, что бы это была оболочка без хорошего парсера.
— Эммануэль

1
Проблема в том, что вам нужно знать, где заканчивается строка, прежде чем вызывать анализатор. С обратными галочками это относительно просто, но с квадратными скобками сложно, так как они используются для различных целей в оболочке. Таким образом, вам нужен парсер дважды и таким образом, которого нет в Bourne Shell.
— Щили
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.