Яка різниця між цитатами "...", "...", $ "..." і $ "..."?


49

Іноді я бачу сценарії використовувати всі ці різні способи процитувати текст: "...", '...', $'...', і $"...". Чому використовується стільки різних видів цитат?

Вони поводяться по-різному чи впливають на те, що я можу зробити всередині них?


1
Можливий дублікат між сайтами. Ця відповідь надає короткий виклад (або посилання на) семантики всіх цитат різних типів.
чепнер

Відповіді:


66

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

Коротко:

  • '...' цілком буквально.
  • "..." дозволяє як змінні, так і вбудовані символи цитати.
  • $'...'виконує схожі символи \n, але не змінює змінні.
  • $"..." є для людських мовних перекладів на баш і ksh.

"Одиночні котирування"

Що б ви не писали між окремими цитатами, трактується буквально і взагалі не обробляється. Підсумки та знаки долара там не мають особливого значення. Це означає, що ви не можете змінити символи зворотної косої риси (включаючи інші одиничні лапки!), Інтерполювати змінну або використовувати будь-яку іншу функцію оболонки.

Усі ці приклади призводять до буквального написання між цитатами:

'hello world'                     => hello world
'/pkg/bin:$PATH'                  => /pkg/bin:$PATH
'hello\nworld'                    => hello\nworld
'`echo abc`'                      => `echo abc`
'I\'dn\'t've'                     => I\dn'tve

Останнє є складним - є два одноцитувані рядки, які виконуються разом із текстом, який не цитується. Перший містить I\. Текст без котирування dn\'tмістить єдину цитату, що вийшов на рівні оболонки , тому він не починає рядок з цитуванням і включається як буквальний символ (так, dn't). Остаточний цитуваний рядок справедливий ve. Усі вони збираються в одне слово звичайним чином, як працює оболонка.

Дещо поширена ідіома для комбінування буквального тексту та змінних полягає в тому, щоб запустити їх так:

'let x="'$PATH\"

призведе до

let x="/usr/bin:/bin"

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


"Подвійні котирування"

Всередині подвійних лапок обробляються два види розширення, і ви можете використовувати зворотну косу рису, щоб уникнути символів, щоб запобігти обробці розширень або втеч.

Існує дві категорії розширення, які відбуваються в подвійних лапках:

Усередині лапок зворотний нахил може стримувати ці розширення, ставлячи його перед $або `. Він також може уникати подвійної подвійної лапки, тому \"включає просто "рядок або інший зворотний ривок. Будь-яка інша косою рисою зберігається буквально - немає жодних виходів, щоб створити інших символів, і вона не знімається.

Деякі з цих прикладів діють інакше, ніж раніше, а деякі не:

"hello world"                     => hello world
"/pkg/bin:$PATH"                  => /pkg/bin:/bin:/usr/bin
"hello\nworld"                    => hello\nworld
"hello\\nworld"                   => hello\nworld
"`echo abc`"                      => abc
"I\'dn\'t've"                     => I\'dn\'t've
"I'dn't've"                       => I'dn't've
"I\"dn\"t've"                     => I"dn"t've

$ 'Цитування ANSI-C'

Цей вид цитування дозволяє обробляти вказівники зворотної косої лінії в стилі С, але не вбудовувати змінні чи підстановки. Це єдиний вид цитування, який підтримує втечі символів .

Це розширення від ksh, яке зараз підтримується в Bash, zsh та деяких інших оболонках. Він ще не є частиною стандарту POSIX і тому максимально портативний сценарій не може його використовувати, але сценарій Bash або ksh є вільним.

Всі ці пагони можуть бути використані з їх значеннями C: \a, \b, \f, \n, \r, \t, \v, і буквальні вислизає \\, \', \", і \?. Вони також підтримують розширення \e(символ втечі) та в Bash та ksh \cx(що було б введено Ctrl-x , наприклад \cM, повернення каретки). Снаряди мають ряд власних подовжень.

Він також дозволяє чотири види втечі загального характеру:

  • \nnn, один байт з восьмеричним значенням nnn
  • \xHH, єдиний байт із шістнадцятковим значенням HH
  • \uHHHH, кодова точка Unicode, шістнадцятковий показник якої - HHHH
  • \UHHHHHHHH, кодова точка Unicode, шістнадцятковий показник якої - HHHHHHHH

Усі ці цифри необов’язкові після першої.

$і `не мають значення і зберігаються буквально, тому ви не можете туди включити змінну.

$'hello world'                    => hello world
$'/pkg/bin:$PATH'                 => /pkg/bin:$PATH
$'hello\nworld'                   => hello
                                     world
$'`echo abc`'                     => `echo abc`
$'I\'dn\'t\'ve'                   => I'dn't've
$'\U1f574\u263A'                  => 🕴☺

Більшість з цих пагонів можна імітувати з допомогою в printfкоманду , хоча POSIX вимагає тільки \\, \a, \b, \f, \n, \r, \t, \v, і \nnnпрацювати там. Ви можете використовувати підстановки команд , щоб вставляти printfв подвійні лапки , якщо це необхідно: "Path:$(printf '\t')$PATH".


$ "Переклад локальної мови"

Це специфічне для ksh та Bash розширення для локалізації текстових рядків на природній мові та шукає частину всередині цитат у каталозі повідомлень. Він спочатку виконує всі розширення подвійних пропозицій. Якщо рядок не знайдено в базі даних перекладів, вона використовується як власний переклад. Вбудоване припущення полягає в тому, що рядки англійською мовою.

Ви, ймовірно, не хочете користуватися цим, але якщо ви бачите його, ви, як правило, трактуєте його як звичайні подвійні лапки.


Одним із зауважень є те, що не існує такого роду цитування, яке дозволяє як розширення вбудованого параметра, так і вбудованих символів. У більшості випадків, коли ви цього хочете, вам краще (безпечніше) використовувати printf:

printf 'New path: \e[1m%s\e[0m' "/pkg/bin:$PATH:"

Це чітко розмежовує, які частини підлягають виконанню символів, а які - значеннями даних.

Інше полягає в тому, що всі ці стилі цитування створюють одне "слово" в оболонці, якщо не використовується $@ або розширення масиву ${x[@]}всередині подвійних лапок. Обидві форми з цитатами завжди є одним словом і більше ніколи не розширюються.


$"..."також з ksh93, доданий до bash в 2.0.
Стефан Шазелас

Немає \cXв zsh. Це \CXабо \C-Xє ( \cвже має особливе значення в echo)
Стефан Шазелас

'let x="'$PATH\"помилково в списку контекстів у оболонках, окрім zshяк $PATHне зазначається (тому це може бути предметом спліт + glob, якого ви тут не хочете).
Стефан Шазелас

Ви можете уточнити, що ви говорите про подібні до Корну оболонки, обробка цитат відрізняється від csh, rc, fish ...
Stéphane Chazelas

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