Первым процессом, который выполняется после работы обычного процесса по выводу информации и отправки к драйверу потока символов консоли (для их реального вывода), является перевод кодов, используемых при обычной работе, в коды, применяемые для печати.
Если консоль работает в режиме UTF-8, то входящие байты сначала организуются в 16-битовый Юникод. В ином случае каждый байт преобразуется согласно текущей таблице перекодировки (которая переводит данные в Юникод). Смотри раздел Наборы символов ниже).
Обычно значения Юникода преобразуются в индекс шрифта, который хранится в видеопамяти таким образом, что соответствующий образ (обнаруженный в видео-ПЗУ) появляется на экране. Заметим, что работа с Юникодом (и текущими аппаратными средствами компьютеров) позволяет одновременно использовать только 512 различных образов.
Если текущим значением Юникода является управляющий символ или если в данный момент обрабатывается экранирующая последовательность, значение будет обрабатываться особым образом. Вместо того, чтобы значение было преобразовало в шрифт и отобразилось как образ, оно приведёт к выполнению определённого действия (например, перемещение курсора) или другой функции управления. Смотрите ниже раздел Управление консолью Linux .
Некорректно явно указывать в программах аппаратные последовательности управление терминалом. Linux поддерживает работу с базой возможностей терминала terminfo (5). Вместо того, чтобы вводить управляющие последовательности вручную, вы, наверняка, захотите использовать для этой работы библиотеку, использующую terminfo, или другие утилиты, такие как ncurses (3), tput (1) или reset (1).
Управляющие символы
Символ считается управляющим, если (до преобразования согласно таблице перекодировки) он содержит один из 14 кодов: 00 (NUL), 07 (BEL), 08 (BS), 09 (HT), 0a (LF), 0b (VT), 0c (FF), 0d (CR), 0e (SO), 0f (SI), 18 (CAN), 1a (SUB), 1b (ESC), 7f (DEL). Можно установить режим "показывать управляющие символы" (см. ниже), при этом символы 07, 09, 0b, 18, 1a, 7f будут выводиться на экран в виде образов. С другой стороны, в режиме UTF-8 все коды с 00 по 1f воспринимаются как управляющие символы, независимо от режима "показа управляющих символов".
Если встречается управляющий символ, то он учитывается немедленно, и никак не влияет в дальнейшем (даже если он стоял в середине экранирующей последовательности), и управляющая последовательность продолжается со следующего символа. Однако, символ ESC, начинающий новую экранирующую последовательность, возможно, отменит незаконченную предыдущую последовательность, а символы CAN и SUB точно закончат любую экранирующую последовательность. Распознаваемыми управляющими символами являются: BEL, BS, HT, LF, VT, FF, CR, SO, SI, CAN, SUB, ESC, DEL, CSI. Они выполняют стандартные для них действия:
BEL (0x07, ^G ) издает звуковой сигнал; BS (0x08, ^H ) удаляет предыдущий символ (смещается влево на один столбец, но не далее, чем за начало строки); HT (0x09, ^I ) перемещается на следующую позицию табуляции или в конец строки, если до этого не было установлено позиций табуляции; LF (0x0A, ^J ), VT (0x0B, ^K ) и FF (0x0C, ^L ) задают перевод строки, а LF/NL (в режиме новой строки) выполняет перевод каретки; CR (0x0D, ^M ) задает перевод каретки; SO (0x0E, ^N ) приводит в действие набор символов G1; SI (0x0F, ^O ) приводит в действие набор символов G0; CAN (0x18, ^X ) и SUB (0x1A, ^Z ) прерывают экранирующую последовательность; ESC (0x1B, ^[ ) начинают экранирующую последовательность; DEL (0x7F) игнорируется; CSI (0x9B) эквивалентно ESC [.
ESC- но не CSI-последовательности
ESC c | RIS | Сброс. |
ESC D | IND | Перевод строки. |
ESC E | NEL | Новая строка. |
ESC H | HTS | Установить позицию табуляции в текущем столбце. |
ESC M | RI | Обратный перевод строки. |
ESC Z | DECID |
Специфическое определение DEC. Ядро
возвращает строку ESC [ ? 6 c, утверждая
что это VT102.
|
ESC 7 | DECSC |
Сохранить текущее состояние (координаты курсора,
атрибуты, наборы символов, указанные G0, G1).
|
ESC 8 | DECRC | Восстановить последнее сохранённое ESC 7 состояние. |
ESC [ | CSI | Начало управляющей последовательности |
ESC % | Начать последовательность с выбором набора символов |
|
ESC % @ | выбор по умолчанию (ISO 646/ISO 8859-1) |
|
ESC % G | выбор UTF-8 |
|
ESC % 8 | выбор UTF-8 (устарела) |
|
ESC # 8 | DECALN | Экранный тест на выравнивание DEC: заполняет экран символами E. |
ESC ( | Начать последовательность с выбором набора символов G0 |
|
ESC (B | выбор по умолчанию (перекодировка ISO 8859-1) |
|
ESC (0 | выбор графической перекодировки VT100 |
|
ESC (U | без перекодировки --- сразу в символьную ROM |
|
ESC (K | перекодировка пользователя --- карта |
|
загружается утилитой mapscrn
(8). |
||
ESC) | Начать последовательность с выбором набора символов G1 |
|
(следом идёт один из символов B, 0, U, K, как с G0). |
||
ESC > | DECPNM | Установить режим ввода цифр для дополнительной клавиатуры |
ESC = | DECPAM | Установить режим управления для дополнительной клавиатуры |
ESC ] | OSC |
(Должно быть: команда операционной системы, OSC)
ESC ] P nrrggbb
: установить палитру, в параметре
задаётся 7 шестнадцатеричных символов после последнего P:-(.
Здесь n
задаёт цвет (0-15), а в rrggbb
указываются
значения красного/зелёного/синего (0-255).
ESC ] R: сбросить палитру
|
CSI-последовательности ECMA-48
CSI (или ESC [) сопровождаются последовательностью параметров, являющихся десятичными номерами, разделёнными точкой с запятой (самый больший из них --- NPAR (16)). Пустой или отсутствующий параметр приравнивается нулю. Последовательность параметров может начинаться одним знаком вопроса.
Тем не менее, после CSI [ (или ESC [ [) считывается единственный символ и оставшаяся часть последовательности игнорируется. (Смысл этого в том, чтобы не отображать функциональную клавишу).
Результат работы CSI-последовательности определяется её конечным символом.
@ | ICH | Вставить N пустых символов. |
A | CUU | Переместить курсор вверх на N строк. |
B | CUD | |
C | CUF | |
D | CUB | Переместить курсор влево на N столбцов. |
E | CNL | Переместить курсор вниз на N строк в столбец 1. |
F | CPL | Переместить курсор вверх на N строк в столбец 1. |
G | CHA | |
H | CUP | Переместить курсор в указанную строку и столбец (начало в 1,1). |
J | ED | Очистить экран (по умолчанию от курсора до конца экрана). |
ESC [ 1 J: очистить от начала до курсора. |
||
ESC [ 2 J: очистить весь экран. |
||
ESC [ 3 J: очистить весь экран, включая буфер |
||
обратной прокрутки (начиная с Linux 3.0). |
||
K | EL | Очистить строку (по умолчанию от курсора до конца строки). |
ESC [ 1 K: очистить от начала строки до курсора. |
||
ESC [ 2 K: очистить всю строку. |
||
L | IL | Вставить N пустых строк. |
M | DL | Удалить N строк. |
P | DCH | Удалить N символов в текущей строке. |
X | ECH | Очистить N символов в текущей строке. |
a | HPR | Переместить курсор вправо на N столбцов. |
c | DA | Ответ по ESC [ ? 6 c: «Я терминал VT102». |
d | VPA | Переместить курсор в указанную строку текущего столбца. |
e | VPR | Переместить курсор вниз на N строк. |
f | HVP | Переместить курсор в указанную строку и столбец. |
g | TBC | Без параметра: очистить текущую позицию табуляции. |
ESC [ 3 g: удалить все позиции табуляции. |
||
h | SM | Режим установки (см. ниже). |
l | RM | Режим сброса (см. ниже). |
m | SGR | Установка атрибутов (см. ниже). |
n | DSR | Отчёт о состоянии (см. ниже). |
q | DECLL | Управление индикаторами на клавиатуре. |
ESC [ 0 q: выключить все индикаторы |
||
ESC [ 1 q: включить Scroll Lock |
||
ESC [ 2 q: включить Num Lock |
||
ESC [ 3 q: включить Caps Lock |
||
r | DECSTBM | Установить область прокрутки; параметрами будут верхняя и нижняя строки. |
s | ? | Сохранить местоположение курсора. |
u | ? | Восстановить местоположение курсора. |
` | HPA | Переместить курсор в указанный столбец текущей строки. |
Установка параметров графики ECMA-48
Последовательность ECMA-48 SGR управляющих символов ESC [ parameters m устанавливает атрибуты экрана. В одной последовательности может быть задано несколько атрибутов. Пустой параметр (между точкой с запятой или начальной строкой или символом завершения) считается нулём.
параметр | результат |
0 | сбросить все атрибуты в их значения по умолчанию |
1 | установить жирный |
2 | установить более яркий (имитируется цветом на цветном дисплее) |
4 |
установить подчеркивание (имитируется цветом на цветном дисплее)
(цвета, используемые для имитации затемнения или подчеркивания, устанавливаются
при помощи ESC ] ...)
|
5 | включить мерцание |
7 | включить инвертирование видео |
10 |
сбросить выбранную перекодировку, флаг управления экраном
и переключить метафлаг (в ECMA-48 указан как "первичный шрифт").
|
11 |
выбрать null-перекодировку, установить флаг управления экраном,
сбросить переключатель метафлага (в ECMA-48 указан как "первый альтернативный шрифт").
|
12 |
выбрать null-перекодировку, установить флаг управления экраном,
установить переключатель метафлага (в ECMA-48 указан как "второй альтернативный шрифт").
Переключение метафлага
вызывает переключение старшего бита в байте
до его перекодировки согласно таблице трансляции.
|
21 | включить нормальную интенсивность (в ECMA-48 указано как "двойное подчёркивание") |
22 | включить нормальную интенсивность |
24 | выключить подчеркивание |
25 | выключить мерцание |
27 | выключить инвертированное видео |
30 | установить чёрный цвет символов |
31 | установить красный цвет символов |
32 | установить зелёный цвет символов |
33 | установить коричневый цвет символов |
34 | установить синий цвет символов |
35 | установить сиреневый цвет символов |
36 | установить голубой цвет символов |
37 | установить белый цвет символов |
38 | включить подчеркивание, установить цвет символов по умолчанию |
39 | выключить подчеркивание, установить цвет символов по умолчанию |
40 | установить чёрный цвет фона |
41 | установить красный цвет фона |
42 | установить зелёный цвет фона |
43 | установить коричневый цвет фона |
44 | установить синий цвет фона |
45 | установить сиреневый цвет фона |
46 | установить голубой цвет фона |
47 | установить белый цвет фона |
49 | установить цвет фона по умолчанию |
Переключатели режимов ECMA-48
ESC [ 3 h DECCRM (по умолчанию выключен): Показывать управляющие символы. ESC [ 4 h DECIM (по умолчанию выключен): Включить режим вставки. ESC [ 20 h LF/NL (по умолчанию выключен): Автоматически выводить код CR после LF, VT или FF.
Команды вывода состояния ECMA-48
ESC [ 5 n Сообщение о состоянии устройства (DSR): Ответом является ESC [ 0 n (терминал в порядке). ESC [ 6 n Сообщение о позиции курсора (CPR): Ответом является ESC [ y ; x R, где x,y являются координатами курсора.
Последовательности спец-режима DEC (DECSET/DECRST)
ESC [ ? 1 h DECCKM (по умолчанию выключено): Если включено, то клавиши курсора посылают префикс ESC O, а не с ESC [. ESC [ ? 3 h DECCOLM (по умолчанию = 80 столбцов): режим переключения количества столбцов 80/132. В исходном коде драйвера указано, что одной этой команды недостаточно; некоторые пользовательские утилиты, использующие нестандартные режимы, такие как resizecons (8), должны менять регистры настройки видеокарты консоли. ESC [ ? 5 h DECSCNM (по умолчанию выключено): Включить инвертированный видеорежим. ESC [ ? 6 h DECOM (по умолчанию выключено): Если включено, то координаты курсора рассматриваются относительно верхнего левого угла области прокрутки. ESC [ ? 7 h DECAWM (по умолчанию включено): Включить режим автопереноса. В этом режиме графический символ, вводящийся после 80-го столбца (или 132-го, если DECCOLM включён), переносится в начало следующей строки. ESC [ ? 8 h DECARM (по умолчанию включено): Включить режим автоповтора символов при вводе с клавиатуры. ESC [ ? 9 h Отчёт X10 о состоянии мыши (по умолчанию выключено): Установить режим отчёта о состоянии мыши, равным 1 (или сбросить в 0), см. ниже. ESC [ ? 25 h DECTECM (по умолчанию включено): Сделать курсор видимым. ESC [ ? 1000 h Отчёт X11 о состоянии мыши (по умолчанию выключено): Установить режим отчёта о состоянии мыши, равным 2 (или сбросить в 0), см. ниже.
Специфические CSI-последовательности консоли Linux
Следующие последовательности не являются ни ECMA-48, ни VT102. Они есть только в драйвере консоли Linux. Цвета в параметрах SGR: 0 = чёрный, 1 = красный, 2 = зелёный, 3 = коричневый, 4 = синий, 5 = сиреневый, 6 = голубой, 7 = белый.
ESC [ 1 ; n ] | Установить цвет n
как цвет подчеркивания |
ESC [ 2 ; n ] | Установить цвет n
как цвет затемнения |
ESC [ 8 ] | Установить текущую пару цветов атрибутами по умолчанию. |
ESC [ 9 ; n ] | Выключение экрана через n
минут. |
ESC [ 10 ; n ] | Установить частоту звукового сигнала (в герцах). |
ESC [ 11 ; n ] | Установить длительность звукового сигнала (в миллисекундах). |
ESC [ 12 ; n ] | Переместить указанную консоль перед остальными. |
ESC [ 13 ] | Включить экран. |
ESC [ 14 ; n ] | Установить интервал отключения питания VESA (в минутах). |
ESC [ 15 ] |
Переместить предыдущую консоль перед остальными
(начиная с Linux 2.6.0).
|
ESC [ 16 ; n ] |
Задать интервал мигания курсора в миллисекундах
(начиная с Linux 4.2)
|
В системе существует два набора символов, называемых G0 и G1, и один из них является текущим набором символов системы (изначально это G0). Ввод ^N заставляет набор G1 стать текущим, ^O делает текущим набор G0.
Данные переменные G0 и G1 указывают на таблицу трансляции и могут меняться пользователем. Изначально они указывают на таблицы a) и b) соответственно. Последовательности ESC (B, ESC (0, ESC (U и ESC (K заставляют G0 ссылаться на таблиц трансляции a), b), c) и d), соответственно. Последовательности ESC) B, ESC) 0, ESC) U, и ESC) K заставляют G1 ссылаться на таблицу трансляции a), b), c) и d), соответственно.
Последовательность ESC c приводит к сбросу терминала, то есть то, что вы хотели бы сделать при наличии «мусора» на экране. Рекомендация, указанная после «echo ^V^O», только сделает G0 текущим набором, но нет никакой гарантии, что G0 указывает на таблицу a). В некоторых дистрибутивах есть программа reset (1), которая всего лишь выполняет команду «echo ^ . Побитовое изображение, соответствующее s, ищется в ПЗУ символов и может меняться при помощи setfont (8).
Параметром для всех созданных xterm (1) экранирующих последовательностей (сигналов от мыши) будет один символ, код которого равен значение +040. Например, "!" соответствует единице. Отчёт системы координат экрана начинается с 1.
В режиме совместимости с X10 при нажатии на кнопки посылаются экранирующие последовательности, в которых кодируется и расположение мыши, и информация о нажатой кнопке. Режим включается при выдаче ESC [ ? 9 h и выключается при выдаче ESC [ ? 9 l. При нажатии на кнопку xterm (1) посылает ESC [ M bxy (6 символов), где b --- это кнопка 1, а x и y равны координатам x и y при нажатии на кнопку. Это такие же коды, какие генерирует и выдаёт ядро.
В обычном режиме отслеживания мыши (который не был реализован в Linux 2.0.24) экранирующие последовательности посылаются и при нажатии и при отпускании кнопки мыши. Также посылается информация о модификаторе. Режим включается при выдаче ESC [ ? 1000 h и выключается при выдаче ESC [ 1000 l. При нажатии или отпускании кнопки xterm (1) выдает ESC [ M bxy . Два младших бита b содержат информацию о кнопках: 0=MB1 нажата, 1=MB2 нажата, 2=MB3 нажата, 3=отпущена. Старшие биты содержат информацию о том, какие модификаторы были нажаты, когда была нажата кнопка. Эта информация складывается при нажатии: 4=Shift, 8=Meta, 16=Control. Ещё раз: x и y являются координатами x и y мыши при обработке события. Координаты верхнего левого угла рассматриваются как (1,1).
Обработка управляющих символов
Тип VT102 также распознает следующие управляющие символы:
NUL (0x00) игнорируется; ENQ (0x05) запускает обратное ответное сообщение; DC1 (0x11, ^Q , XON) возобновляет передачу; DC3 (0x13, ^S , XOFF) заставляет VT100 игнорировать (и останавливать передачу) всех кодов за исключением XOFF и XON.
VT100-подобную обработку DC1/DC3 можно включить в драйвере терминала.
ESC ] 0 ; txt ST | Установить имя значка и заголовок окна равным txt
. |
ESC ] 1 ; txt ST | Установить имя значка равным txt
. |
ESC ] 2 ; txt ST | Установить заголовок окна равным txt
. |
ESC ] 4 ; num ; txt ST | Установить цвет ANSI num
равным txt
. |
ESC ] 10 ; txt ST | Установить цвет динамического текста равным txt
. |
ESC ] 4 6 ; name ST | Изменить файл журнала на name
(обычно отключено |
в параметрах компиляции) |
|
ESC ] 5 0 ; fn ST | Установить шрифт fn
. |
Распознаются следующие параметры с несколько измененным значением (больше сохраняется состояние, поведение ближе к VT100/VT220):
ESC 7 DECSC | Сохранить курсор | |
ESC 8 DECRC | Восстановить курсор |
Также распознается
Также распознается ESC % и предоставляется более полная реализация UTF-8 чем в консоли Linux.
Последовательности CSI
Старые версии xterm (1), например из X11R5, воспринимают мерцание SGR как жирность SGR. В более новых версиях, в которых реализованы цвета ANSI, например в XFree86 3.1.2A 1995 года, атрибут мерцания отображается цветом. В современных версиях xterm мерцание SGR реализовано в виде мерцающего текста, который можно также сделать цветным в качестве альтернативы отображения SGR. Исходные версии X11R6 не распознают настройки цвета SGR вплоть до версии X11R6.8, в которую был включён XFree86 xterm. Все последовательности CSI ECMA-48 CSI, понимаемые Linux, также понимает xterm , однако в xterm (1) реализовано несколько управляющих последовательностей ECMA-48 и DEC, которые не понимаются Linux.
Программа xterm (1) распознаёт все последовательности спец-режимов DEC, описанных выше, но ни одной последовательности спец-режимов Linux. О собственных спец-режимах xterm (1) можно прочитать в документе Управляющие последовательности Xterm , написанном Edward Moy, Stephen Gildea и Thomas E. Dickey и доступном в дистрибутиве X. Этот документ хотя и сокращённый, но всё равно намного больше данной справочной страницы. Хронологический обзор в
описывает изменения в xterm.
Программа vttest
демонстрирует многие из этих управляющих последовательностей. В исходном дистрибутиве xterm (1) также содержатся примеры сценариев, которые учат работать с другими свойствами.
Некоторые старые версии ядер (после 2.0) анализируют 8-битные управляющие последовательности. В них ("управляющие коды C1") используются коды от 128 до 159 для замены ESC [, ESC ] и подобных начальных двухбайтовых управляющих последовательностей. Они частично существуют в современных ядрах (или не распознаются или не работают из-за поддержки UTF-8), и реализованы не полностью, и должны расцениваться как ненадежные.
Последовательности "спец-режима" Linux не учитывают правила ECMA-48 для управляющих последовательностей спец-режима. В частности, они заканчиваются ] и не используют стандартный символ завершения. Последовательность OSC (установить палитру) --- большая проблема, так как xterm (1) рассматривает её как управляющую последовательность, которой требуется окончание строки (ST). В отличие от последовательностей setterm (1), которые будут проигнорированы (так как они не являются правильными управляющими последовательностями), последовательность палитры приведёт к подвисанию xterm (1) (хотя нажав клавишу return это исправится). Чтобы приспособить приложения, в которых жёстко заданы управляющие последовательности Linux, установите ресурс xterm (1) brokenLinuxOSC равным true.
В старой версии данного документа предполагалось, что Linux распознаёт управляющую последовательность ECMA-48 для невидимости текста. Она игнорируется.
ESC-последовательности - это специальные символьные комбинации, которые
представляют пробельные символы и неграфические символы в строках и символьных
константах.
Их типичное использование связано со спецификацией таких действий, как
возврат каретки и табуляция, а также для задания литеральных представлений
символов, таких как символ "двойная кавычка" ("). ESC-последовательность состоит
из символа "обратная косая черта" (\), за которым следует буква, знаки
пунктуации "одиночная кавычка" ("), "двойные кавычки" ("), "обратная косая
черта" (\) или комбинация цифр.
Если обратная косая черта предшествует символу, не включенному в этот
список, то обратная косая черта игнорируется, а символ представляется как
литеральный. Например, изображение "\с" представляет символ "с" в литеральной
строке или константе-символе.
Последовательности "\ddd" и "\xdd" позволяют задать любой символ в ASCII
(Американский стандартный код информационного интерфейса) как последовательность
трех восьмеричных цифр или двух шестнадцатеричных цифр. Например, символ пробела
может быть задан как \010 или \х08. Код ASCII нуль может быть задан как \0 или
\х0. В восьмеричной ESC-последовательности могут быть использованы от одной до
трех восьмеричных цифр. Например, символ пробела может быть задан как \10. Точно
так же в шестнадцатеричной ESC-последовательности могут быть использованы от
одной до двух шестнадцатеричных цифр. Так, шестнадцатеричная последовательность
для символа пробела может быть задана как \х08 или \х8.
Следует отметить, что когда используется восьмеричная или шестнадцатеричная
ESC-последовательность в строках, то нужно полностью задавать все цифры
ESC-последовательности (три цифры для восьмеричной и две цифры для
шестнадцатеричной ESC-последовательностей). Иначе, если символ, непосредственно
следующий за ESC-последовательностью, случайно окажется восьмеричной или
шестнадцатеричной цифрой, то он проинтерпретируется как часть
последовательности. Например, строка \х7Ве11 при выводе на печать будет
выглядеть как ell, поскольку \х7В проинтерпретируется как символ левой фигурной
скобки (). Строка \х07Ве11 будет правильным представлением символа звонок с
последующим словом Bell.
ESC-последовательности позволяют посылать неграфические управляющие символы
к внешним устройствам. Например, ESC-последовательность \033 часто используется
как первый символ команд управления терминалом и принтером. Неграфические
символы всегда должны представляться ESC-последовательностями, поскольку
непосредственное использование в программах на Си неграфических символов будет
иметь непредсказуемый результат.
Символ "обратная косая черта" (\) помимо определения ESC-последовательностей
используется также как символ продолжения строки в препроцессорных определениях.
Если символ "новая строка" следует за символом "обратная косая черта" (\),
то новая строка игнорируется и следующая строка рассматривается как часть
предыдущей строки.
Когда printf - мало, а ncurses - много
Когда данных становится слишком много, бывает не хватает стандартного вывода printf в консольной программе. Особенно если различных событий много и различные данные превращаются в безумный листинг. Эти данные могут поступать от контроллера через UART, и тут нечего и думать о какой-то gui-программе. Может так же быть и обычный bash-скрипт, к которому хочется прикрутить какой-никакой псевдографический интерфейс.
Скажу сразу, может поначалу показаться это изобретением велосипеда, ведь есть прекрасная библиотека ncurses. Ничуть не умаляю её достоинств, но часто её возможности бывают слишком избыточны. Плюс она слабо переносима в контроллеры и там уж точно избыточна. А вот пару макросов и функций для работы с псевдографикой можно набросать и самим.
Пусть у нас есть контроллер, где к 8-ми разрядному порту подключены контактные датчики, которые могут принимать состояние ВКЛ и ВЫКЛ, есть аналоговый трёхосевой датчик, и мы должны выводить их состояние, плюс в контроллере есть время, дата, и мы хотим контролировать правильность отображения времени; и наконец там может случится событие (например сбой по питанию), где мы должны срочно информировать оператора. Подытожим:
Вроде как идея понятна, но как это реализовать в терминале? А вот тут начинается настоящая магия! "А теперь надо обязательно дунуть! Если не дунуть, никакого чуда не произойдет! " Амаяк Акопян
Сегодня терминал представляет собой программу, которая может быть виртуальным терминалом, как в linux или терминалом, которая работает с СОМ-портом. Все эти терминалы, даже классический HyperTerminal отвечают некоторым стандартам. Как не сложно догадаться, такими терминалами нужно управлять. Есть обычные ASCII символы, которые отображаются на экране, а есть специальные последовательности символов, которые позволяют задавать координаты курсора, очищать экран, задавать цвет и т.п. В своих статьях на хабре и гиктаймс я уже неоднократно касался тем ESC-последовательностей. Мы их применяли в управлении дисплеем при (описание в спойлере, который никто не читал), и в статье про , который так же управляется ESC-последовательностями.
Если кто-то из вас застал времена BBS, то вы помните какие «красивые» были эти доски: цветные, у которых были определённые поля ввода-вывода информации и т.п. Вся эта радость выводилась с помощью таких Управляющих символов. Символ считается управляющим, если (до преобразования согласно таблице перекодировки) он содержит один из 14-и кодов: 00 (NUL), 0x07 (BEL), 0x08 (BS), 0x09 (HT), 0x0a (LF), 0x0b (VT), 0x0c (FF), 0x0d (CR), 0x0e (SO), 0x0f (SI), 0x18 (CAN), 0x1a (SUB), 0x1b (ESC), 0x7f (DEL). Нас интересует в первую очередь символ ESC=0x1b, "\033" или же "\e". Подробнее о этих последовательностях можно прочитать в мануалах man console_codes, либо в интернете на русском .
Кроме управления курсором, можно ещё раскрашивать терминал в разные цвета (если он, конечно, цветной). Проверить цвета вашего терминала можно простейшим BASH-скриптом:
For fgbg in 38 48 ; do #Foreground/Background
for color in {0..256} ; do #Colors
#Display the color
echo -en "\e[${fgbg};5;${color}m ${color}\t\e ; then
echo #New line
fi
done
echo #New line
done
exit 0
Результат выполнения будет примерно такой:
Вот, вы уже владеете необходимой информацией, чтобы сделать весёлые пасхалки в BASH-скриптах, как например картинка, вынесенная в заголовок поста.
#define home() printf(ESC " OSC (Сокращение "команд операционной системы")
ESC ] P nrrggbb: установить палитру с параметрами,
заданными в 7-и шестнадцатеричных разрядах после последнейP:-(.
Здесь n является цветом 0-16, а rrggbb указывает
на использование красного/зеленого/голубого цвета (0-255).
ESC ] R: сбросить палитру
ECMA-48 CSI-последовательности
CSI (или ESC [) сопровождаются последовательностью
параметров, являющихся десятичными номерами, разделенными
точкой с запятой (самый больший из них - NPAR (16)).
"Пустой" параметр (или отсутствие его) приравнивается
нулю. Последовательность параметров может начинаться
одним знаком вопроса. Тем не менее, после CSI [ (или ESC
[ [) считывается единственный символ и оставшаяся часть
последовательности игнорируется. (Смысл этого в том,
чтобы игнорировать отображаемую функциональную клавишу).
Результат задания CSI-последовательности определяется ее
конечным символом.
@ ICH Вставить N пустых символов.
A CUU Переместить курсор вверх на N рядов.
B CUD Переместить курсор вниз на N рядов.
C CUF Переместить курсор вправо на N столбцов.
D CUB Переместить курсор влево на N столбцов.
E CNL Переместить курсор вниз на N рядов, в столбец #1.
F CPL Переместить курсор вверх на N рядов, в столбец #1.
G CHA Переместить курсор в указанный столбец текущего ряда.
H CUP Переместить курсор в указанный ряд и столбец (начало в 1,1).
J ED "Очистить" экран (по умолчанию от курсора до конца экрана).
ESC [ 1 J: "очистить" от начала столбца до курсора.
ESC [ 2 J: "очистить" весь экран.
K EL "Очистить" строку (по умолчанию от курсора до ее конца).
ESC [ 1 K: "очистить" от начала строки до курсора.
ESC [ 2 K: "очистить" всю строку.
L IL Вставить N пустых строк.
M DL Удалить N строк.
P DCH Удалить (со смещением в строке) N символов в текущей строке.
X ECH "Очистить" (без смещения в строке) N символов в текущей строке.
a HPR Переместить курсор вправо на N столбцов.
c DA Ответить ESC [ ? 6 c: `Я являюсь VT102".
d VPA Переместить курсор в указанный ряд текущего столбца.
e VPR Переместить курсор вниз на N рядов.
f HVP Переместить курсор в указанный ряд и столбец.
g TBC Без параметров: "очистить" текущую позицию табуляции.
ESC [ 3 g: удалить все позиции табуляции.
h SM Режим установки (см. ниже).
l RM Режим сброса (см. ниже).
m SGR Установка атрибутов (см. ниже).
n DSR Отчет о статусе (см. ниже).
q DECLL Установить режимы работы индикаторов на клавиатуре.
ESC [ 0 q: выключить все индикаторы
ESC [ 1 q: включить индикатор "Scroll Lock"
ESC [ 2 q: включить индикатор "Num Lock"
ESC [ 3 q: включить индикатор "Caps Lock"
r DECSTBM Установить область прокрутки; параметрами будут верхний и нижний ряды.
s ? Сохранить местоположение курсора.
u ? Восстановить местоположение курсора.
` HPA Переместить курсор в указанный столбец текущего ряда.
ECMA-48 Установка параметров графики
Последовательность ECMA-48 SGR управляющих символов ESC [
m устанавливает атрибуты экрана. Несколько
атрибутов могут быть заданы в одной последовательности.
Парам. результат
0 сбросить все атрибуты в их значения по умолчанию
1 установить жирный шрифт
2 установить более яркий (имитированное цветом на цветном дисплее)
4 установить подчеркивание (имитированное цветом на цветном дисплее);
цвета, используемые для имитации затемнения или подчеркивания, устанавливаются
при помощи ESC ] ...
5 включить мерцание
7 включить режим инвертированного видео
10 сбросить выбранное распределение, флаги управления экраном
и переключить метафлаг
11 выбрать null-распределение, установить флаг управления экраном,
сбросить переключатель метафлага.
12 выбрать null-распределение, установить флаг управления экраном,
включить переключатель метафлага. Переключение метафлага
задает переключение старшего бита в байте
до его трансформации согласно таблице распределения.
21 включить режим нормальной интенсивности (несовместимо с ECMA-48)
22 выключить режим нормальной интенсивности
24 выключить подчеркивание
25 выключить мерцание
27 выключить инвертированное видео
30 установить черный цвет символов
31 установить красный цвет символов
32 установить зеленый цвет символов
33 установить коричневый цвет символов
34 установить синий цвет символов
35 установить сиреневый цвет символов
36 установить голубой цвет символов
37 установить белый цвет символов
38 включить подчеркивание, установить цвет символов по умолчанию
39 выключить подчеркивание, установить цвет символов по умолчанию
40 установить черный цвет фона
41 установить красный цвет фона
42 установить зеленый цвет фона
43 установить коричневый цвет фона
44 установить синий цвет фона
45 установить сиреневый цвет фона
46 установить голубой цвет фона
47 установить белый цвет фона
49 установить цвет фона по умолчанию
ECMA-48 Переключение режимов
ESC [ 3 h
DECCRM (по умолчанию выключено): Показывать
управляющие символы.
ESC [ 4 h
DECIM (по умолчанию выключено): Установить режим
вставки/замены.
ESC [ 20 h
LF/NL (по умолчанию выключено): Автоматически
выводить код CR после кодов: LF, VT или FF.
ECMA-48 Команды сообщения статуса
ESC [ 5 n
Сообщение о статусе устройства (DSR): Ответом
является ESC [ 0 n (Терминал в порядке).
ESC [ 6 n
Сообщение о позиции курсора (CPR): Ответом является
ESC [ y ; x R, где x,y являются координатами
курсора.
DEC-последовательности частного режима (DECSET/DECRST)
Не описаны в ECMA-48. Далее будут перечислены
последовательности установки режимов; в последовательности
для сброса режимов последний знак `h" заменяется на `l".
ESC [ ? 1 h
DECCKM (по умолчанию выключено): Если включено, то
клавиши курсора выдают сигнал, начинающийся с ESC
O, а не с ESC [.
ESC [ ? 3 h
DECCOLM (по умолчанию выключено = 80 столбцов):
режим переключения количества столбцов на 80 или
132. В исходных версиях драйвера задано, что одной
этой команды недостаточно; некоторые
пользовательские утилиты, использующие
нестандартные режимы, такие, как resizecons(8),
должны менять регистры настройки консольной
видеокарты.
ESC [ ? 5 h
DECSCNM (по умолчанию выключено): Включить
инвертированный видеорежим.
ESC [ ? 6 h
DECOM (по умолчанию выключено): Если включено, то
координаты курсора рассматриваются относительно
верхнего левого угла в области прокрутки.
ESC [ ? 7 h
DECAWM (по умолчанию включено): Включить режим
автопереноса. В этом режиме графический символ,
вводящийся после столбца #80 (или #132, если DEC-
COLM включено), переносится в начало следующей
строки.
ESC [ ? 8 h
DECARM (по умолчанию включено): Включить режим
автоповтора символов при нажатии клавиши
клавиатуры.
ESC [ ? 9 h
X10 Отчет о состоянии мыши (по умолчанию
мыши, равным единице или нулю (сброс), см. ниже.
ESC [ ? 25 h
DECCM (по умолчанию включено): Сделать курсор
видимым.
ESC [ ? 1000 h
X11 Отчет о состоянии мыши (по умолчанию
выключено): Установить режим отчета о состоянии
мыши, равным 2-м или нулю (сброс), см. ниже.
Частные последовательности CSI консоли Linux
Следующие последовательности не являются ни ECMA-48-, ни
VT102-последовательностями. Они являются "родными" для
драйвера консоли Linux. Цвета в параметрах SGR: 0 =
черный, 1 = красный, 2 = зеленый, 3 = коричневый, 4 =
синий, 5 = сиреневый, 6 = голубой, 7 = белый.
ESC [ 1 ; n ] Установить цвет n как цвет подчеркивания
ESC [ 2 ; n ] Установить цвет n как цвет затемнения
ESC [ 8 ] Установить текущую пару цветов атрибутами по умолчанию.
ESC [ 9 ; n ] Установить начало "очистки" экрана через n минут.
ESC [ 10 ; n ] Установить частоту звукового сигнала (в герцах).
ESC [ 11 ; n ] Установить длительность звукового сигнала в(миллисекундах).
ESC [ 12 ; n ] Переместить указанную консоль впереди остальных.
ESC [ 13 ] Восстановить экран после "очистки".
ESC [ 14 ; n ] Установить VESA-интервал отключения (в минутах).
НАБОРЫ СИМВОЛОВ
Ядро располагает информацией о 4-х типах перевода байтов в
символы консоли экрана. Эти четыре таблицы являются
трансформирующими: a) Latin1 -> PC, b) графика VT100 ->
PC, c) PC -> PC, d) определяется пользователем. В системе
вообще существует два набора символов, называемых G0 и G1,
и один из них является текущим набором системы (изначально
это G0). Ввод ^N заставляет набор G1 стать текущим, ^O
делает текущим набор G0. Переменные G0 и G1 указывают на
таблицы символов и могут меняться пользователем.
Изначально они указывают на таблицы a) и b)
соответственно. Последовательности ESC (B и ESC (0 и
ESC (U и ESC (K заставляют G0 ссылаться на таблицы
перевода a), b), c) и d) соответственно.
Последовательности ESC) B и ESC) 0 и ESC) U и ESC) K
заставляют G1 ссылаться на таблицы перевода a), b), c) и
d) соответственно. Последовательность ESC c приводит к
сбросу терминала, то есть к тому, что Вам необходимо при
наличии "мусора" на экране. Рекомендация, указанная после
"echo ^V^O", только сделает G0 текущим набором, но нет
никакой гарантии, что G0 будет указывать на таблицу a). В
некоторых версиях есть программа reset(1), которая всего
лишь выполняет команду "echo ^ . Побитное
изображение, соответствующее s, ищется в ПЗУ символов и
может меняться при помощи setfont(8).
РАБОТА С МЫШЬЮ
Система для отслеживания работы мыши предполагает выдачу
xterm-совместимых сигналов о статусе мыши. Так как драйвер
консоли не распознает такого устройства, как мышь (или ее
типа), то эти сигналы отправляются во входной поток
консоли, только когда драйвер виртуального терминала
получает сигнал ioctl об обновлении статуса мыши. Эти
сигналы ioctls должны генерироваться пользовательскими
приложениями, поддерживающими работу с мышью (такими, как
демон gpm(8)). Параметром для всех созданных xterm
ESC-последовательностей (сигналов о перемещении мыши)
будет один символ, код которого равен value+040. Например,
`!" соответствует единице. Система координат экрана при
отслеживании работы мыши базирована на знаке единицы. В
режиме совместимости с X10 при нажатии на кнопки
посылаются ESC-последовательности, в которых кодируется и
состояние мыши, и информация о нажатой кнопке. Режим
запускается при выдаче ESC [ ? 9 h и выключается при
выдаче ESC [ ? 9 l. При нажатии на кнопку xterm посылает
ESC [ M bxy (6 символов), где b - это кнопка-1, а x и y
равны координатам x и y при нажатии на эту кнопку. Это
такие же коды, какие генерируют и выдают ядро системы. В
обычном режиме отслеживания мыши (который не был
реализован в Linux 2.0.24) ESC-последовательности
посылаются при нажатии и при отпускании кнопки мыши.
Также посылается информация о модификаторе. Запускается
режим при выдаче ESC [ ? 1000 h и выключается при выдаче
ESC [ 1000 l. При нажатии и отпускании кнопки xterm
выдает ESC [ M bxy. Два нижних бита b содержат информацию
о кнопках: 0=MB1 нажата, 1=MB2 нажата, 2=MB3 нажата,
3=отпущена. Старшие биты содержат информацию о том, какие
модификаторы были выключены когда кнопка была нажата. Эта
информация складывается при нажатии: 4=Shift, 8=Meta,
16=Control. Еще раз: x и y являются координатами x и y
мыши при обработке события. Координаты верхнего левого
угла рассматриваются как (1,1).
СРАВНЕНИЕ С ДРУГИМИ ТЕРМИНАЛАМИ
Множество других типов терминалов описаны наподобие
консоли Linux (как `VT100-совместимые"). Далее мы обсудим
различия между Linux- консолью и двумя другими важнейшими
типами, DEC VT102 и xterm(1).
Обработка управляющих символов
Тип vt102 также распознает следующие управляющие символы:
NUL (0x00) был проигнорирован;
ENQ (0x05) запущено обратное ответное сообщение;
DC1 (0x11, ^Q, XON) продолженная передача;
DC3 (0x13, ^S, XOFF) указывает, что vt100 необходимо
игнорировать и останавливать передачу всех кодов за
исключением XOFF и XON
VT100-подобная DC1/DC3 обработка может быть запущена
драйвером tty.
Программа xterm (в режиме vt100) распознает управляющие
следующие символы: BEL, BS, HT, LF, VT, FF, CR, SO, SI,
ESC.
ESC-последовательности
VT100-последовательности консоли, не реализованные в
консоли Linux:
ESC N SS2 Сдвиг на 2. (Выбрать набор символов G2 только для следующего
символа.)
ESC O SS3 Сдвиг на 3. (Выбрать набор символов G3 только для следующего
символа.)
ESC P DCS Строка управления устройством (заканчивается на ESC \)
ESC X SOS Начало строки.
ESC ^ PM Частное сообщение (заканчивается на ESC \)
ESC \ ST Завершающий 0 строки
ESC * ... Определить набор символов G2
ESC + ... Определить набор символов G3
Программа xterm (в режиме vt100) распознает: ESC c, ESC #
8, ESC >, ESC =, ESC D, ESC E, ESC H, ESC M, ESC N, ESC O,
ESC P ... ESC ESC Z (оно выдает последовательности ESC [
? 1 ; 2 c ответ: `Я являюсь vt100 с улучшенными
видеопараметрами") и ESC ^ ... ESC с теми же значениями,
какие указаны выше. Принимаются: ESC (, ESC), ESC *,
ESC +,- сопровождаемые 0, A, B для специальных символов
DEC и режима рисования линий, UK и USASCII соответственно.
Принимаются ESC ] для установки работы таких ресурсов,
как:
ESC ] 0 ; txt BEL Установить имя иконки и заголовок окна в режиме txt.
ESC ] 1 ; txt BEL Установить имя иконки в режиме txt.
ESC ] 2 ; txt BEL Установить заголовок окна в режиме txt.
ESC ] 4 6 ; name BEL Сменить файл логов на name (обычно отключено
параметрами компиляции)
ESC ] 5 0 ; fn BEL Установить шрифт fn.
Распознаются следующие параметры с несколько измененным
значением:
ESC F Курсор в нижний левый угол экрана (если разрешено
ресурсом hpLowerleftBugCompat)
ESC l Блокирование памяти (для HP-терминалов).
Блокирует память выше курсора.
ESC m Разблокирование памяти (для HP-терминалов).
ESC n LS2 Ввод набора символов G2.
ESC o LS3 Ввод набора символов G3.
ESC | LS3R Ввод набора символов G3 в качестве GR.
ESC } LS2R Ввод набора символов G2 в качестве GR.
Не имеет видимого эффекта в xterm.
ESC ~ LS1R Ввод набора символов G1 в качестве GR.
Не имеет видимого эффекта в xterm.
Не распознается ESC % ...
CSI-последовательности
Программа xterm (по данным XFree86 3.1.2G) не распознает
мерцание или режим невидимости SGRs. Версии X11R6 не
распознают цветоустановки SGR. Все другие ECMA-48
CSI-последовательности, распознаваемые Linux, также
распознаются xterm и наоборот. Программа xterm будет
распознавать все последовательности частного режима DEC,
перечисленные выше, но не будут распознавать ни одну из
последовательностей частного режима в Linux. Для
обсуждения последовательностей частного режима для xterm
обратитесь к документу XtermControlSequences, созданного
Edward Moy и Stephen Gildea и сопровождаемого
дистрибутивом X Window System.
НАЙДЕННЫЕ ОШИБКИ
В версии 2.0.23 набор CSI является неправильным и
недейственным, NUL не игнорируется внутри
ESC-последовательностей.