Коли ви натискаєте 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 (який трапляється виділити ^X
s у зворотному відео), спираючись на :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 локалі відображатимуться як ^�
... і т.д.
bash
цеreadline
обробка цих матеріалів, а для більшості інших - це драйвер Tty.