Отправляет email-рассылки с помощью сервиса Sendsay

Программирование на shell и awk

  Все выпуски  

Что еще могут esc-последовательности и как их правильно использовать?


Информационный Канал Subscribe.Ru


Выпуск #3

Всем привет! Буду краток. Курс держим тот же. Цель - свобода маневра. Тему читаем дальше.

Что еще могут esc-последовательности
и как их правильно использовать?

Управлять перемещением курсора по экрану:
esc[s
или esc7
запомнить положение курсора
esc[u
или esc8
восстановить запомненное положение курсора
esccочистить экран и установить курсор в левый верхний угол
esc[nAвверх на n строк
esc[nB
или esc[ne
вниз на n строк
esc[nC
или esc[na
вправо на n позиций
esc[nDвлево на n позиций
esc[nEв начало строки и на n строк вниз
esc[nFв начало строки и на n строк вверх
esc[n1;n2H
или esc[n1;n2f
переместить в позицию n2 строки n1
esc[nZна n табуляций назад (как tab, но в обратную сторону)
esc[nв той же строке в позицию n
esc[ndв той же позиции в строку n
escMсдвинуть курсор на строчку вверх, если он находится в самой верхней строке, то сдвинуть содержимое экрана на строчку вниз

Очищать части экрана:
esc[0Jот курсора до конца экрана
esc[1Jот начала экрана до курсора
esc[2Jвесь экран
esc[0Kот курсора до конца строки
esc[1Kот начала строки до курсора
esc[2Kвсю строку
esc[nXочистить n знаков справа от позиции курсора

Раздвигать и сдвигать строки на экране:
esc[nLвставить n пустых строк ниже текущей строки
esc[nMудалить n строк ниже текущей строки
esc[nPудалить n знаков справа от курсора (в пределах строки)
esc[n@вставить n знаков справа от курсора (в пределах строки)

Проведем испытания. Начнем с подготовки рабочего пространства. Выполните команду clear (или просто нажмите Ctrl+L). Затем - более хитрую (напомню, что символы ^[ появляются в результате нажатия клавиш Ctrl+L,Esc):
 $ echo '^[[10;10Habc^[[5dXYZ'



             XYZ
 $



          abc
Переходим к «разбору полетов». Как вы видите, esc-последовательность ^[[10;10H переместила курсор в 10-ю позицию 10-й строки экрана и начиная с этой позиции был осуществлен вывод символов abc. Потом esc-последовательность ^[[5d переместила курсор немного назад в 5-ю строку, неизменив его позиции в строке. После этого echo напечатала символы XYZ и вывела завершающий символ перевода строки. Поэтому-то приглашение командного интерпретатора в виде у.е. появилось в следующей (шестой) строке.

Довольно просто, не так ли? Однако, если вспомнить, что в UNIX для ввода/вывода можно использовать множество различных терминалов, отлищающихся и размером экрана (количество строк и символов в строке), и командами управления экраном, и кодами, которые генерируют клавиши и т. п., то возникает вопрос: как одни и те же программы умудряются корректно взаимодействовать со всем этим «зоопарком»?

Наведение порядка в этом «зоосаде» обеспечивают два компонента UNIX: база данных и библиотека подпрограмм. В первом описаны поддерживаемые терминалом функции, а второй используется для выполнения запросов к базе данных. Каждый тип терминала в этой базе имеет свое название и перечень его свойств. Изначально эта информация хранилась в файле termcap (от terminal capabilities - возможности терминала). C годами termcap очень вырос и в семействе AT&T юниксов превратился в базу данных terminfo. В ней, чтобы не хранить всю информацию в одном большом файле, описание каждого терминала компилируется и сохраняется в отдельном файле.

Свойствами терминала могут быть:

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

Названия свойств стандартизированы и неизменны (почти:), а их значения наоборот изменяются в зависимости от типа терминала. В качестве примера ниже приведено несколько стандартных обозначений характеристик терминалов:
 termcapterminfo
число символов в строкеcocols
число строк на экранеlilines
очистить экрансlclear
включить повышенную яркостьmdbold
включить миганиеmbblink
включить реверсное отображениеmrrev
установить цвет символовAFsetaf
установить цвет фонаABsetab
переместить курсорcmcup
подать звуковой сигналblbel

Более подробную информацию можно получить в манах по termcap и terminfo.

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

Что же делать, если у вас возникло желание написать сценарий, который работал бы с любым, поддерживаемым операцинной системой, терминалом с одинаковой (или уменьшенной) функциональностью? Попробуйте воспользоваться утилитой tput. Синтаксис у нее следующий:
tput [-T тип_терминала] название_свойства [параметр(ы) ...]

В качестве значения аргумента название_свойства может быть задано любое имя из списка свойств базы данных termcap и/или terminfo для терминала указанного в тип_терминала. Если этот аргумент опущен, то tput будет использовать значение переменной TERM.

Для кодирования цветов используются следующие числа (в скобках указываются цвета для режима повышенной яркости):

0 - черный (серый)
1 - красный (розовый)
2 - зеленый (салатовый)
3 - коричневый (желтый)
4 - синий (светло-синий)
5 - фиолетовый (лиловый)
6 - бирюзовый (голубой)
7 - белый (ярко-белый)

Однако, не все так просто в нашем королевстве. Будьте готовы к тому, что в одних системах (BSD) tput будет ожидать название_свойства в стиле termcap, а в других (System V) - в стиле terminfo. Примеры:

$ tput AF 2      # теперь буковки будут зелененькие
$ tput setaf 2   # если сразу не сработало, то теперь уж точно
$ tput cm 24 35  # переместить курсор в 24-ю строку, а про позицию догадайтесь сами
$ tput cup 24 35 # аналогично
$ tput li        # сколько у меня строк на эране?
30
$ tput lines     # а у вас?

Всем, кто хочет изучить материальную часть более предметно, рекомендую поэкспериментировать с утилитами, которые конвертируют записи базы terminfo в termcap и наоборот. В BSD-системах это tconv, а в Linux и юниксах ветви AT&T - infocmp. Вот вам еще примерчики:

$ infocmp -C|grep cl #вывод в формате termcap
     :cl=\E[H\E[J:cm=\E[%i%d;%dH:cr=^M:cs=\E[%i%d;%dr:\
$ infocmp -I|grep cl #вывод в формате terminfo
     clear=\E[H\E[J, el1=\E[1K, el=\E[K, ed=\E[J,

Конечно же, существует много случаев, когда использование esc-последовательностей напрямую оправдано. Приведу в качестве примера фрагмент файла /etc/rc.status дистрибутива SuSE Linux (комментарии мои):

if test "$TERM" != "raw" && stty size > /dev/null 2>&1 ; then
# если наш терминал понимает, что такое ширина и высота,
# то назначаем кодам esc-последовательностей понятные названия
         esc=echo -en "\033"
        extd="${esc}[1m"
        warn="${esc}[1;31m"
        done="${esc}[1;32m"
        attn="${esc}[1;33m"
        norm=echo -en "${esc}[m\017"
        stat=echo -en "\015${esc}[${COLUMNS}C${esc}[10D"
        # ... неинтересное пропускаем
  rc_done_up="${esc}[1A${rc_done}"
rc_failed_up="${esc}[1A${rc_failed}"
    rc_reset="${norm}"
     rc_save="${esc}7"
  rc_restore="${esc}8"
    function rc_cuu () { echo -en "\033[${1}A"; }
    # и даже определяем функцию для перемещения по экрану вверх на заданное число строк
else
# ну а если терминал не знает где у него верх, а где низ, то ведем себя проще
# и выдаем информацию построчно без выкрутасов, чтобы люди к нам тянулись :) ...

И небольшое замечание относительно ДОСа. Помните такую ОС? Так вот, если к ней прикрутить стандартный драйвер ANSI.SYS, то все вышеперечисленные esc-последовательности будут работать и там.


В в табличке из предыдущего выпуска рассылки потерялась последняя строчка, но неторопитесь объявлять ее в розыск - она уже нашлась:
==================================================================
k | n=k - установка      | n=k+30 - установка      | цвет символов
  |       режима         |          цвета символов | в режиме
  |       отображения    | n=k+40 - установка      | повышенной
  |       символов       |          цвета фона     | яркости
--|----------------------|-------------------------|--------------
7 | реверсный            | белый                   | ярко-белый
==================================================================



Ведущий рассылки Big Shadow

http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться
Убрать рекламу

В избранное