Яка різниця між $ (stuff) та `stuff '?


265

Для підстановки команд є два синтаксиси: з дужками в доларах і з зворотними посиланнями. Запуск top -p $(pidof init)і top -p `pidof init`дає однаковий вихід. Це два способи зробити одне і те ж чи є відмінності?


18
Дивіться також: BashFAQ / 082 .
Денніс Вільямсон

42
На секунду там я подумав, що це питання jQuery.
Девід Мердок

Результат може залежати від оболонки - деякі підтримують і те й інше.
artdanil

Відповіді:


359

Зворотні котирування в старому стилі ` `обробляють зворотні коси та гніздування дещо інакше. Новий стиль $()інтерпретує все між собою ( )як команду.

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
Єдине, що я хотів би додати, - це те, що я дзвоню '(' батько, а не дужка (що є '[').
Кендалл Гельмстеттер Гельнер

@Kendall: і ось я подумав, що "{" - ліва дужка за всі ті роки ...
SamB

5
@Sam: { }зазвичай називається "фігурними дужками" або "дужками" en.wikipedia.org/wiki/Braces_(punctuation)#Braces
Jørn Schou-Rode

2
Я також позначаю "{" як фігурні дужки. Хоча це здається дивним, вам потрібно додати класифікатор "фігурним", якщо ви називаєте дужки інших речей ... Я думаю, це лише тому, що вони насправді згортаються.
Кендалл Гельмстетер Гельнер

1
@slim Я не знаю на клавіатурах США та Великобританії, але на іспанських клавіатурах `це мертвий ключ, тому мені доводиться вводити або подвійний зворотній зв'язок (щось, про що я зазвичай забуваю, я навіть можу зробити), або зворотній вибір, а потім пробіл, який є біль.
Darkhogg

41

Очевидна відмінність, яку я зауважую, полягає в тому, що ви не можете гніздити задники, поки ви можете гніздо $(). Можливо, обидва існують із спадкових причин. Аналогічно, команди .і sourceкоманди є синонімами.


10
Деякі оболонки, отримані Борном, не розпізнають source. Тире - один із прикладів.
Денніс Вільямсон

14
Це не правда. Ви можете вкласти гнізда на будь-який рівень, тільки більш болісно. Зауважте, що і те, $(...)і `...`стандартне (останнє застаріле), а .стандартне, але неsource
Стефан Шазелас

3
Виправлення, лише в тому випадку, якщо (t)cshвони не можуть бути вкладені. (t)cshне підтримую, $(...)хоча. Вони все ж підтримують source(і ні .).
Стефан Шазелас

28

$()не працює зі старою оболонкою Борна. Але це було років кілька десятиліть , так як я працював зі старою оболонки Bourne.


Старі, як у 1970-х та на початку 1980-х, правда?
Крістофер

6

Ще одна примітка, $()буде використовувати більше системного ресурсу, ніж використання зворотних посилань, але трохи швидше.

Під час засвоєння сценаріїв оболонки Unix Рандал К. Майкл провів тест у главі під назвою "24 способи обробки файлу по черзі".


2
Ця претензія є нісенітницею. Немає причини, чому це повинно бути швидшим, оскільки це просто використання іншого позначення для аналізатора.
schily

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

3
Я схильний би погодитися з @schily ... чому б це зайняло більше ресурсів?
Wildcard

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
Хоча $ () може виглядати приємно, це біль при впровадженні відповідного аналізатора, оскільки він вимагає подвійного рекурсивного аналізатора.
schily

6
@schily З іншого боку, що було б оболонкою без хорошого розбору.
Еммануїл

1
Проблема полягає в тому, що вам потрібно знати, де закінчується рядок, перш ніж викликати аналізатор. Це є порівняно простим із підкладками, але важко з дужками, оскільки вони використовуються для різних цілей у оболонці. Тож вам потрібен аналізатор двічі і таким чином, який не існує в оболонці Борна.
schily
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.