Поняття backtick (`)


35

Я пробую команду

$ b=5; echo `$b`;
-bash: 5: command not found

але він не друкує 5, як належить. Що я тут пропускаю?

Що означає `(backquote / backtick) у командах? здається, говорить, що `оцінює команди всередині і замінює їх на вихід.


8
Зауважте, що зворотні посилання не рекомендуються, оскільки ви втратите можливість робити вкладені заміни виконання. Insetad, $ (деякийкоманда) є кращим. Імхо, це покращує читабельність.
Томмі

6
@Tommy, Ні, задні посилання можуть бути вкладені, але це стає несподіваним кошмаром, особливо при подвійному цитуванні.
Стефан Шазелас

Відповіді:


52

Текст між зворотними посиланнями виконується та замінюється виведенням команди (мінус кінцеві символи нового рядка, і будьте обережні, що поведінка оболонки змінюється, коли у виході є символи NUL). Це називається заміщенням команд, оскільки воно заміщене результатом команди. Отже, якщо ви хочете надрукувати 5, ви не можете використовувати зворотні посилання, ви можете використовувати лапки, як-от echo "$b"або просто відкинути будь-яку лапочку та використовувати echo $b.

Як бачите, оскільки $bмістить 5, при використанні зворотних посилань bashнамагається запустити команду, 5і оскільки такої команди немає, вона не працює з повідомленням про помилку.

Щоб зрозуміти, як працюють задні посилання, спробуйте виконати наступне:

$ A=`cat /etc/passwd | head -n1`
$ echo "$A"

cat /etc/passwd |head -n1слід надрукувати перший рядок /etc/passwdфайлу. Але оскільки ми використовуємо backticks, він не друкує це на консолі. Натомість він зберігається у Aзмінній. Ви можете перегукнутися $Aз цим. Зауважте, що більш ефективним способом друку першого рядка є використання командиhead -n1 /etc/passwd але я хотів би зазначити, що вираження всередині задників не повинно бути простим.

Отже, якщо перший рядок / etc / passwd є root:x:0:0:root:/root:/bin/bash, перша команда буде динамічно замінена bash наA="root:x:0:0:root:/root:/bin/bash" .

Зауважте, що цей синтаксис має оболонку Борна. Цитування та втеча швидко стає кошмаром, особливо коли ти починаєш їх гніздувати. Ksh представив $(...)альтернативу, яка зараз стандартизована ( POSIX ) та підтримується всіма оболонками (навіть оболонкою Bourne від Unix v9). Тож вам слід користуватися$(...) замість них сьогодні, якщо вам не потрібно переносити на дуже старі оболонки Борна.

Також зауважте, що виведення `...`та $(...)підлягають розщепленню слів та створенню імен файлів так само, як і розширення змінної (в zsh, лише розщеплення слів), тому, як правило, потрібно цитувати у контекстах списку.


1
Привіт @Krzysztof, це корисно! "оскільки $ b містить 5, bash намагається запустити команду 5" - саме те, що я шукав
coolcric

you can use quotation marks, like echo "$b"=> чи "" робить щось особливе? Здається echo $b, так само спрацювало б.
Tootsie Rolls

@Anita: Загалом, лапки мають деякі особливі речі (це змінює спосіб поводження з особливими символами - особливо пробіли), але в цьому випадку їх можна викинути без особливих проблем. Це тому, що ніяких спеціальних символів не використовується, і echoкоманда не хвилює кількість аргументів, які вона отримує, тому якщо bвсередині є кілька пробілів, вони отримають кілька аргументів і все одно їх роздрукують. Це може бути не в інших командах (особливо, коли змінна не встановлена), тому я схильний завжди оточувати змінні лапками.
Кшиштоф Адамський

Було б добре, якби (POSIX)було посилання на фактичний стандарт.
erikbwork

1
@ erikb85: Ця записка не була додана мною, але я редагував її за посиланням, як ви запропонували :)
Кшиштоф Адамський

11

Зворотний вибір робить саме те, що ви говорите. Ви встановили змінну на ціле число. Коли ви помістите цю змінну всередині задників, bash спробує виконати її як команду. Оскільки це не команда, ви отримуєте помилку, яку ви побачили.

Що ви хочете зробити, це просто:

$ b=5; echo $b

Щоб краще зрозуміти основи, порівняйте:

$ b=5; a=`echo $b`; echo $a
  5

8

Переходячи крок за кроком, ваша лінія повинна пояснити це.

$ b=5; echo `$b`;
  1. встановлює змінну b до 5
  2. оцінює $b(ефективно працює)5 )
  3. echoе результат оцінки вище.

Так що так, очікуваний вихід отриманий. Ви оцінюєте вміст змінної, а не фактичну команду, яку ви вважали. Все, що ви поміщаєте всередину задніх посилань, - це оцінювання (запуск) у новій (під) оболонці.


привіт @gertvdijk, дякую за ваш пост! Я думав, що `повертає все, що залишилося, після оцінки його вмісту. Отже, я думав, що $ $ поверне 5 за ехо, щоб надрукувати його
coolcric
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.