Як використовувати спеціальний символ як звичайний?


13

Багато питань, таких як "Як набрати char (") з подвійною цитатою? " нас запитують, і ми не хочемо захаращувати нашу спільноту однаковою відповіддю (введіть її так, \"ніби не укладено в 's, "якщо вкладено в 's.) Отже, питання тут.

Не можна вводити спеціальні символи в термінал, як звичайні, наприклад, ця команда не вдасться:

echo Updates (11)

Отже, як набрати ці символи в терміналі, ніби вони були нормальними?

!#$^&*?[](){}<>~;'"\|<space><tab><newline>

Немає оболонки Unix, яку я знаю, де спеціальне повернення каретки . =, @і %є спеціальними в деяких оболонках в деяких контекстах.
Стефан Шазелас

@ StéphaneChazelas Umm ... повернення каретки ( ^M) діє як подача рядків ( ^J) для мене (Ubuntu 14.04, ш).
EKons

Ні, ваші термінальні перетворення драйвера ^Mдля ^Jна вході , але ^Mне навмисно для оболонки і не обов'язково в лапках. Наберіть echo ^V^M | hdі ви побачите символ 0d (і 0a, доданий ехо).
Стефан Шазелас

@ StéphaneChazelas Umm ... Я не знаю, що hdтаке, можливо, xxdце краще, як шестигранний глядач.
EKons

Що б не було. Використовуйте POSIX od -tx1або sed -n lxxd vim, якщо у вас немає hd. Деякі системи також мають cat -vteабоcat -A
Stéphane Chazelas

Відповіді:


27

Це дуже залежить від оболонки. Перегляньте посібник з оболонкою на деталі.

Також зауважте, що деякі персонажі є особливими лише в деяких контекстах. Наприклад, у більшості оболонок, *і ?вони є лише спеціальними у контекстах списку, в POSIX або csh-подібних оболонках, ~є особливим лише на початку слова або слідом за деякими символами на зразок :. Те саме для =в zsh. У деяких оболонках [є спеціальним лише тоді, коли він відповідає (з деякими обмеженнями) a ].

У деяких оболонках, як-от bashабо yash, спеціальні символи, як розмежувачі пустих маркерів, також різняться залежно від місцевості.

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

Оболонки, подібні до Борна

Короткий огляд оболонок, подібних до Борна (тобто оболонок, які, як відомо, називались shу тій чи іншій системі з 80-х років):

Оболонка Борна

Спеціальні символи:

  • "\'&|;()^`<>$, пробіл, новий рядок та вкладка є спеціальними у простих командних рядках, коли вони не цитуються.
  • #( За винятком ранньої версії) є особливим на початку рядка або після пропуску, табуляції або некотируваних &|()^<>;`.
  • {і }особливі лише тим, що вони є ключовими словами оболонки (тому лише слова в командному положенні).
  • *?[є спеціальними як глобальні оператори, тому лише в контекстах списку. У випадку з [тим, [...]що це глобальний оператор, [або його ]потрібно лише цитувати, щоб усунути особливе значення.
  • =є особливим у контекстах, де він розглядається як оператор присвоєння. Тобто, у простій команді для всіх слів, які не слідують за аргументом (крім після set -k).

Цитуючи операторів

  • \цитує всіх спеціальних символів, окрім нового рядка ( \<newline>це спосіб продовжити довгий логічний рядок на наступний фізичний рядок, щоб ця послідовність була видалена). Зауважте, що backticks додає додаткової складності, як і всередині них, \використовується спочатку, щоб уникнути закриття backtick та допомогти парсеру. Всередині подвійні лапки \можуть використовуватися лише для виходу із себе ", $і `( \<newline>все ще є продовженням рядка). Всередині документа-документа тут, за винятком ". \це єдиний спосіб уникнути символів, що знаходяться тут.
  • "..."подвійні лапки уникають усіх символів, крім себе \, $та `.
  • '...' Одиночні цитати уникають усіх персонажів, крім самого себе.

Оболонки POSIX

Оболонки POSIX поводяться переважно як оболонка Борна, за винятком того, що:

ksh

як POSIX за винятком того, що:

  • {string}є особливим, якщо рядок містить без котирування ,(або ..в деяких випадках і з деякими версіями).
  • ksh93 має додаткового спеціального оператора цитування: $'...'зі складними правилами. Цей оператор також знайдений (з деякими варіаціями) в bash, zsh, mkshта FreeBSD і BusyBox sh.
  • ksh93також є $"..."оператор котирування, який працює як, "..."за винятком того, що рядок підлягає локалізації (може бути налаштований так, що вона перекладається на мову користувача). mkshігнорує $в $"...".

bash

як, ksh93але:

  • в однобайтових локальних символах усі порожні (відповідно до локалі) символи розглядаються як роздільники (наприклад, пробіл чи вкладка). Насправді це означає, що ви повинні навести всі байти з 8-го бітового набору, якщо вони можуть бути порожнім символом у якомусь локалі.
  • Коли розширення історії csh увімкнено, як у інтерактивних екземплярах, !у деяких контекстах особливе, а подвійні цитати не завжди уникають цього. І ^є особливим на початку команди.

zsh

як, ksh93але:

  • та ж примітка, що і bashдля розширення історії csh
  • =особливий як перший символ слова ( =lsрозширюється на /bin/ls).
  • {а }також може відкривати та закривати командні групи, коли їх не розмежовують (як у {echo text}роботах на зразок Борна { echo text;}).
  • за винятком [поодинки, [потреби, які цитуються, навіть якщо вони не закриті ].
  • З extendedglobувімкненою опцією #, ^та ~є глобальні оператори.
  • З bracecclваріантом, {non-empty-string}особливим.
  • $"..." не підтримується.
  • як особлива химерність, ?не є особливою, якщо слідувати за %(навіть цитованим або розширеним) на початку слова (щоб дозволити %?nameзавдання завдання)
  • rcquotesваріант (не включена за замовчуванням) дозволяє ввести одиничні лапки як ''всередині одиночних лапок а ля rc(див . нижче)

yash

як, POSIXкрім цього.

  • всі порожні символи розглядаються як роздільники.
  • За допомогою цього brace-expandваріанту реалізується розширення брекетів у стилі zsh.

Для всіх оболонок існують деякі спеціальні контексти, де цитування працює по-різному. Тут ми вже згадували документи та бекстейки, але є також [[...]]у ksh та декількох інших оболонках, POSIX $((...)), caseконструкціях ...

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

Підсумок

У оболонках, подібних до Борна !#$^&*?[(){}<>~;'"`\|=, SPC, TAB, NEWLINE та деякі байти з восьмим бітовим набором є або можуть бути спеціальними (принаймні в деяких контекстах).

Щоб вилучити спеціальне значення, щоб вони трактувались буквально, ви використовуєте цитування.

Використання:

  • '...' щоб видалити особливе значення кожного персонажа:

    printf '%s\n' '\/\/ Those $quoted$ strings are passed literally as
    single arguments (without the enclosing quotes) to `printf`'
  • \ щоб видалити спеціальне значення лише одного символу:

    printf '<%s>\n' foo bar\ baz #comment

    Зверху \буквально передається лише пробіл, який передує a printf. Інші з них оболонки розглядаються як обмежувачі лексеми.

  • використовувати "..."процитувати символи в той же час дозволяючи розширення параметрів ( $var, $#, ${foo#bar}...), арифметична розкладання ( $((1+1))також $[1+1]в деяких оболонках) і підстановки команд ( $(...)або старою формою `...`. На Насправді, більшу частину часу, ви хочете помістити ці розширення всередині подвійні лапки в будь-якому випадку . Ви можете використовувати \всередині, "..."щоб видалити особливе значення символів, які все ще є спеціальними (але лише їх).
  • якщо рядок містить 'символ, ви можете використовувати '...'для відпочинку і використовувати інші механізми , які в лапки можуть цитувати 'як "'"або \'чи (якщо такий є) $'\'':

    echo 'This is "tricky", isn'\''t it?'
  • Використовуйте сучасну $(...)форму підстановки команд. Використовуйте старий лише `...`для сумісності з оболонкою Bourne, тобто з дуже старою системою, і лише у змінних призначеннях, як у не використовується:

    echo "`echo "foo bar"`"

    Що не працюватиме з оболонкою Bourne або AT&T версіями ksh. Або:

    echo "`echo \"foo bar\"`"

    Який буде працювати з Bourne та AT&T ksh, але не з yash, а використовувати:

    var=`echo "foo bar"`; echo "$var"

    яка працюватиме з усіма.

    Порядне введення їх у подвійні лапки також неможливо, тому знову використовуйте змінні. Також остерігайтесь спеціальної обробки зворотної косої риски:

    var=`printf '%s\n' '\\'`

    Збережеться лише одна косою рисою всередині $var, оскільки існує додатковий рівень обробки зворотної косої риски (для \, `і $(а також, "якщо цитується, окрім yash) в межах зворотних посилань, тому вам потрібно

    var=`printf '%s\n' '\\\\'`

    або

    var=`printf '%s\n' '\\\'

    замість цього.

Csh родина

csh і tcsh мають суттєво різний синтаксис, хоча є ще багато спільного з оболонкою Bourne, оскільки вони мають спільну спадщину.

Спеціальні символи:

  • "\'&|;()^`<>$, пробіл, нова лінія та вкладка є спеціальними скрізь, коли вони не цитуються.
  • #(csh - оболонка, яка вводиться #як лідер коментарів) є особливою на початку сценарію або після пропуску без котирування, вкладки чи нового рядка.
  • *?[ є спеціальними як глобальні оператори, так що в списках контекстів
  • {non-empty-string} є спеціальним (csh - оболонка, яка ввела розширення дужок).
  • !і ^є спеціальними як частина розширення історії (знову ж таки, csh винахід), а правила цитування є особливими.
  • ~ (tilde розширення також csh винахід) є особливим у деяких контекстах.

Цитуючи операторів

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

  • \уникає одного символу, за винятком нового рядка (те саме, що для оболонки Борна). Це єдиний оператор котирування, який може вийти з ладу !. \<newline>не уникає цього, але перетворює його з сепаратора команд у роздільник токенів (як пробіл)
  • "..."вислизає все символи , крім самого, $, `, нового рядка і !. На відміну від оболонки Борна, ви не можете використовувати \для втечі $та `всередині "...", але ви можете використовувати \для втечі !чи нової лінії (але не себе, за винятком випадків, коли до !або нового рядка). Буквал !є, "\!"а літерал \!є "\\!".
  • '...' уникає всіх персонажів, окрім себе, !та нового рядка. Як і в подвійних котируваннях, !і в новому рядку можна уникнути зворотної косої риски.
  • підміна команд відбувається лише через `...`синтаксис і навряд чи може бути надійно використана.
  • змінна заміна також досить погано розроблена і схильна до помилок. $var:qОператор допомагає писати більш надійний код з участю змінних.

Підсумок

Тримайтеся подалі від csh, якщо можете. Якщо ви не можете використовувати:

  • одинарні цитати, щоб процитувати більшість символів. !і новий рядок ще потрібен \.
  • \ може втекти від більшості персонажів
  • "..."може дозволити деякі розширення всередині нього, але це досить баггі, якщо вони вставляють символи нового рядка та / або зворотній косий риси, найкраще використовувати лише окремі лапки та $var:qдля змінного розширення. Якщо вам потрібно надійно з'єднати елементи масиву, вам потрібно буде використовувати цикли.

rc сім'я

rc- це plan9оболонка та подібні до її нащадків esі akangaперенесена на Unix та unix- like . Це оболонка з набагато чистішим і кращим синтаксисом, і той, який би кожен використовував, якби ми не застрягли з оболонками, подібними до Борна, для зворотної сумісності.

rc/akanga

Спеціальні символи

  • #;&|^$=`'{}()<>, SPC, TAB та NEWLINE завжди особливі, коли їх не котирують.
  • *?[ є глобальними операторами.

Оператор цитування

'...'є єдиним оператором котирування. Літерал 'пишеться в ''межах одного лапки, як у:

 echo 'it''s so simple isn''t it?'

es

esможна було розглядати як експериментальну оболонку на основі rc.

Однак у нього є кілька відмінностей. Цікавим для цього Q / A є те, що \це також оператор котирування (який цитує всі спеціальні символи, окрім нового рядка), а також може бути використаний для введення послідовностей евакуації, як \nдля нового рядка, \bдля зворотної косої риски ...

риба

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

спеціальні символи

  • "'\()$%{}^<>;&|завжди особливий, коли його не цитують (відзначте %(для розширення PID) як істотну відмінність від інших оболонок, і `не є спеціальним)
  • # (коментар) спеціальний, якщо слідує пробіл, котирування, новий рядок або ;&|^<>
  • *?(але не [...]) глобальних операторів

Цитуючи операторів

  • \цитує єдиний спеціальний символ, окрім нового рядка, але будьте обережні, він також подвоюється як вступник послідовності C ( \n, \b...). IOW, \nце не котирування, nа новий рядок.
  • "..."цитує все, окрім себе, $і для зменшення цих показників можна використовувати зворотний кут і нахил. \<newline>є продовженням лінії (видалено) всередині "...".
  • '...'цитує все, окрім себе \, і ви можете використовувати зворотний нахил, щоб уникнути цих.

Я включив тільки спеціальний, у всіх контекстах (так , що cдіє так само , як \c, cневиходу c: command not foundна STDERR і т.д.) І я кажу про shтут. Крім того, пам’ятайте, що це питання "очищення", тобто воно охоплює всіх таких символів, тому не потрібно задавати 19+ питань. Питання було розміщено завдяки інциденту, що для різних таких персонажів задаються різні запитання, ми, безумовно, хочемо прибирати тут!
EKons

Ну, ?[є глобальні оператори, але не особливі у всіх контекстах, але, *здається, так, тому що echo *погано echoє вміст поточного каталогу (нічого не уникаючи). echo ?перегукується з буквальним ?і echo [повторюється буквальним [. Крім того, ]є глобусним спонукачем теж.
EKons

1
@ ΈρικΚωνσταντόπουλος, *як глобус розширюється на всі не приховані файли, ?на не приховані односимвольні файли, [a-z]на файли, ім'я яких є одним символом між a і z тощо. Якщо вони не відповідають жодному файлу (як у вашому випадку для ?), залежно від оболонки, ви отримуєте помилку невідповідності або шаблон розширюється до себе. У будь-якому випадку, навіть на оболонці, де вони розширюються на себе, їм потрібно цитувати, якщо вони можуть відповідати файлу.
Стефан Шазелас

Але, не як глобус, *все-таки розширюється на щось.
EKons

@ ΈρικΚωνσταντόπουλος, *це як ?, якщо він не збігається (лише для випадку *, коли в поточному каталозі є лише приховані файли, тому a*що там немає файлу, ім'я якого починається з a...), воно або розширюється на сама по собі ( в більшості Bourne-подібних оболонок), або видає помилку немає матчів ( csh, tcsh, fish(попередження), zsh, bash -O failglob, ранні Unix оболонки), (або нічого не містить, з можливістю nullglob деяких оболонок або , якщо є ще один шаблон , який розширюється в щось у csh, tcsh, zsh -o cshnullglob, ранні оболонки Unix).
Стефан Шазелас

4

1. Втеча

Увімкніть усі ці символи з таким \, як це (не працює на нових рядках / поверненнях каретки):

$ echo Use a \"\\\" symbol to escape characters.
Use a "\" symbol to escape characters.

2. Подвійне цитування

Укладіть весь текст у "s, як це:

$ var=variables;echo "Enclose text in \"s. You can also use $var in them. `echo Surprise!!!`"
Enclose text in "s. You can also use variables in them. Surprise!!!

3. Одноцінна цитата

Те саме, що і з подвійною цитатою, але особливої ​​лексеми немає.

$ proof=proveit;echo 'This should not read "proveit": $proof'
This should not read "proveit": $proof

1
Ви описуєте поведінку fishоболонки, а не оболонок, подібних до Борна, де одна котировка цитує кожного персонажа (зворотний косий рядок не особливий '...'). Зауважте, що в fish, %також є особливим символом.
Стефан Шазелас

@ StéphaneChazelas Я не знаю, як це fishпрацює, але мій досвід полягає в тому, що sh, як echo '\\'наслідок , відлуння \ та echo '\''відлуння '.
EKons

1
echo '\\'Виводи \ тому, що ваші echoрозширюють послідовності відбору ANSI C ( для цього echoпотрібні деякі реалізації echo -e '\\'). printf '%s\n' '\\'виходи \\.
Стефан Шазелас

Зауважте, що shне ідентифікується конкретна оболонка, існує і було багато різних, часто не сумісних оболонок sh.
Стефан Шазелас

@ StéphaneChazelas О добре, я зараз це зміню. До речі, чи \'є спеціальний маркер всередині одноцитованої послідовності символів?
EKons
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.