Як по-різному відображати контрольні символи (^ C, ^ D, ^ [, ...) в оболонці


13

Коли ви вводите контрольні символи в оболонці, вони відображаються, використовуючи те, що називається "позначення карет". Наприклад, про втечу пишеться як ^[у позначеннях карет.

Мені подобається налаштувати мою башмаку, щоб вона виглядала круто. Я, наприклад, змінив своє PS1і PS2став кольоровим. Тепер я хочу, щоб контрольні символи набули унікального вигляду, а також зробити їх більш відмітними від звичайних символів.

$ # Here I type CTRL-C to abort the command.
$ blahblah^C
          ^^ I want these two characters to be displayed differently

Чи є спосіб, щоб моя оболонка виділила контрольні символи по-різному?

Чи можна змусити відображати їх жирним шрифтом або, можливо, відображати їх у різних кольорах зі звичайного тексту?

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

Зауважте, що я не знаю, на якому рівні відбувається виділення контрольних символів. Я спершу подумав, що це саме в оболонці. Тепер я почув, що саме лінія читання контролює, як контрольні символи в оболонках, як bash . Тож питання позначене тегом, readlineі я все ще шукаю відповіді.


чому ви думаєте, чому оболонка їх виділяє? адже bashце readlineобробка цих матеріалів, а для більшості інших - це драйвер Tty.
mikeserv

Я не знав. Саме тому я написав записку. Це було моєю здогадкою, оскільки інші програми люблять viі lessчасто виділяють контрольні символи по-різному від звичайного тексту. Я відредагую питання з цією інформацією. Дякую!
wefwefa3

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

Readline використовується іншими програмами, але також вона є частиною bash: це бібліотека, пов'язана з нею. І сьогоднішні снаряди, особливо башти, роблять майже все, що можна придумати.
alexis

Просто використовуйте те, zshщо робить це поза коробкою.
Стефан Шазелас

Відповіді:


20

Коли ви натискаєте Ctrl+X, ваш емулятор термінала записує байт 0x18 на головну сторону псевдотермінальної пари.

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

Команда, яка налаштовує дисципліну tty line - це sttyкоманда.

Під час запуску німого додатка, подібного до catцього, не обізнаний і не байдуже, чи є його stdin терміналом чи ні, термінал перебуває в канонічному режимі за замовчуванням, де дисципліна tty line реалізує редактор грубої лінії .

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

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

Якщо ви запустите stty -aкоманду, ви побачите поточні налаштування, які використовуються для німих програм . Ви , ймовірно , щоб побачити icanon, echoі що echoctlнастройки включені.

Це означає, що:

  • icanon: увімкнено редактор сирої лінії.
  • echo: Символи типу (що емулятор терміналу записує в основній частині) є відлунням назад (доступні для читання з допомогою емулятора терміналу).
  • echoctl: замість того, щоб перегукуватися з Asis, контрольні символи перегукуються як ^X.

Отже, скажімо, ви набираєте A B Backspace-aka-Ctrl+H/? C Ctrl+X Backspace Return.

Ваш емулятор терміналу буде відправити: AB\bC\x18\b\r. Дисципліна ліній буде повторюватися назад AB\b \bC^X\b \b\b \b\r\n, і програма, яка читає вхід з підлеглого боку ( /dev/pts/x), прочитає AC\n.

Все, що бачить програма, є AC\n, і лише тоді, коли ти натиснеш, Enterщоб він не міг контролювати вихід ^X.

Ви помітите, що для відлуння перше ^H( ^?з деякими терміналами, див. eraseНастройку) призвело до \b \bповернення до терміналу. Це послідовність , щоб перемістити курсор назад, перезапис з простором, переміщати курсор назад, в той час як другий ^Hв результаті , \b \b\b \bщоб стерти ці два ^і Xсимволи.

Сам ^X(0x18) перекладався на ^та Xдля виведення. Мовляв B, він не потрапив до програми, оскільки ми видалили його за допомогою Backspace.

\r(aka ^M) було переведено на \r\n( ^M^J) для відлуння та \n( ^J) для програми.

Отже, які наші варіанти для цих німих додатків:

  • відключити echo( stty -echo). Це ефективно змінює спосіб відлуння символів управління, шляхом ... нічого не повторюючи. Насправді не рішення.
  • відключити echoctl. Це змінює спосіб керування символами (крім ^H, ^M... та всіх інших, що використовуються редактором рядків). Потім вони перегукуються як є. Наприклад, символ ESC надсилається як байт \e( ^[/ 0x1b) (який розпізнається терміналом початку запущеної послідовності), ^Gви надсилаєте \a(BEL, роблячи сигнал терміналу) ... Не варіант .
  • вимкнути редактор грубої лінії ( stty -icanon). Це насправді не варіант, оскільки сирі програми стануть набагато менш корисними.
  • відредагуйте код ядра, щоб змінити поведінку дисципліни в рядку tty, щоб відлуння керуючого символу надсилалося \e[7m^X\e[mзамість просто ^X(тут \e[7mзазвичай вмикається зворотне відео у більшості терміналів).

Можливим може бути використання обгортки, такої як rlwrapбрудна хак, щоб додати модний редактор рядків до німих програм. Ця обгортка фактично намагається замінити простий read()s з термінального пристрою на дзвінки в редактор рядків читання рядків (які змінюють режим дисципліни tty line).

Ідучи ще далі, ви можете навіть спробувати такі рішення, як це викрадає весь вхід з терміналу, щоб пройти через редактор рядків zsh (який трапляється виділити ^Xs у зворотному відео), спираючись на :execфункцію екрана GNU .

Тепер для додатків, які реалізують свій власний редактор рядків, вирішувати, як виконано ехо, залежить від них. bashвикористовує лінію читання для тієї, яка не підтримує налаштування того, як звуки контрольних символів перегукуються.

Бо zshдивіться:

info --index-search='highlighting, special characters' zsh

zshвиділяє символи, що не друкуються, за замовчуванням. Ви можете налаштувати виділення, наприклад:

zle_highlight=(special:fg=white,bg=red)

Для білого на червоному виділення для цих спеціальних символів.

Текстове представлення цих символів не можна настроювати.

В UTF-8 локалі, 0x18 буде надано , як ^X, \u378, \U7fffffff(два нерозподілені точки Юникода коду) , як <0378>, <7FFFFFFF>, \u200b(НЕ-дійсно для друку Юникода характеру) , як <200B>.

\x80у iso8859-1 локалі відображатимуться як ^�... і т.д.


3

Я зазвичай маю цей код у своєму .bashrc файлі:

function get_exit_status()
{
        local code=$?
        if [ $code -ne 0 ]
        then
                printf $'\001\033[31m\002'"($code)"$'\001\033[0m\002'" "
        fi
}

а потім я викликаю цю функцію в моєму PS1

PS1='\u@\h \w $(get_exit_status)'

Якщо натиснути ^ C, ви побачите це у своєму запиті

I@mycomputer ~ ^C
I@mycomputer ~ (130)

Усі коди статусу виходу, які не є "0", будуть запропоновані.


$? розширюється до статусу виходу в PS1, наприклад PS1 = '$? \ u @ \ h \ w'
teknopaul
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.