Канонический режим, редактирование строки и специальные символы
Терминал может быть настроен на самые разные режимы в соответствии с типом работающих с ним программ; работа этих режимов поддерживается соответствующей дисциплиной линии связи. Например, экранному редактору может понадобиться максимальная свобода действий, поэтому он может перевести терминал в режим прямого доступа (raw mode), при котором дисциплина линии связи просто передает символы программе по мере их поступления, без всякой обработки.
Вместе с тем ОС UNIX не была бы универсальной программной средой, если бы всем программам приходилось бы иметь дело с деталями управления терминалом. Поэтому стандартная дисциплина линии связи обеспечивает также режим работы, специально приспособленный для простого интерактивного использования на основе построчного ввода. Этот режим называется каноническим режим терминала (canonical mode) и используется командным интерпретатором, редактором ed и аналогичными программами.
В каноническом режиме драйвер терминала выполняет специальные действия при нажатии специальных клавиш. Многие из этих действий относятся к редактированию строки. Вследствие этого, если терминал находится в каноническом режиме, то ввод в программе осуществляется целыми строками (подробнее об этом ниже).
Наиболее часто используемой в каноническом режиме клавишей редактирования является клавиша erase, нажатие которой приводит к стиранию предыдущего символа в строке. Например, следующий клавиатурный ввод
$ whp<erase>o
за которым следует перевод строки, приведет к тому, что драйвер терминала передаст командному интерпретатору строку
who. Если терминал настроен правильно, то символ р должен быть стерт с экрана.
В качестве символа erase пользователем может быть задано любое значение ASCII. Наиболее часто для этих целей используется символ ASCII backspace (возврат).
На уровне оболочки проще всего поменять этот символ при помощи команды stty, например
$ stty erase "^h"
задает в качестве символа erase комбинацию Ctrl+H,
которая является еще одним именем для символа возврата. Обратите внимание, что зачастую можно набрать строку "^h", а не нажимать саму комбинацию клавиш Ctrl+H.
Ниже следует систематическое описание других символов, определенных в спецификации XSI и имеющих особое значение для оболочки в каноническом режиме. Если не указано иначе, их точные значения могут быть установлены пользователем или администратором системы.
kill |
Приводит к стиранию всех символов до начала строки. Поэтому входная последовательность $ echo < kill > who за которой следует новая строка, приводит к выполнению команды who. По умолчанию значение символа kill равно Ctrl+?, часто также используются комбинации клавиш Ctrl+X и Ctrl+U. Можно поменять символ kill при помощи команды: $ stty kill <новый_символ> |
intr |
Символ прерывания. Если пользователь набирает его, то программе, выполняющей чтение с терминала, а также всем другим процессам, которые считают терминал своим управляющим терминалом, посылается сигнал SIGINT. Такие программы, как командный интерпретатор, перехватывают этот сигнал, поскольку по умолчанию сигнал SIGINT приводит к завершению программы. Одно из значений для символа intr по умолчанию равно символу ASCII delete (удалить), который часто называется DEL. Вместо него может также использоваться символ Ctrl+C. Для изменения текущего значения символа intr на уровне оболочки используйте команду: $ stty intr <новый_символ> |
quit |
Обратитесь к главе 6 за описанием обработки сигналов quit. Если пользователь набирает этот символ, то группе процессов, связанной с терминалом, посылается сигнал SIGQUIT. Командный интерпретатор перехватывает этот сигнал, остальные пользовательские процессы также имеют возможность перехватить и обработать этот сигнал. Как уже описывалось в главе 6, действием этого сигнала по умолчанию является сброс образа памяти процесса на диск и аварийное завершение, сопровождаемое выводом сообщения «Quit – core dumped». Обычно символ quit – это символ ASCII FS, или Ctrl+\. Его можно изменить, выполнив команду: $ stty quit <новый_символ> |
eof |
Этот символ используется для обозначения окончания входного потока с терминала (для этого он должен быть единственным символом в начале новой строки). Стандартным начальным значением для него является символ ASCII eof, известный также как Ctrl+D. Его можно изменить, выполнив команду: $ stty eof <новый_символ> |
nl |
Это обычный разделитель строк. Он всегда имеет значение ASCII символа line-feed (перевод строки), который соответствует символу newline (новая строка) в языке С. Он не может быть изменен или установлен пользователем. На терминалах, которые посылают вместо символа line-feed символ carriage-return (возврат каретки), дисциплина линии связи может быть настроена так, чтобы преобразовывать возврат каретки в перевод строки |
еоl |
Еще один разделитель строк, который действует так же, как и nl. Обычно не используется и поэтому имеет по умолчанию значение символа ASCII NULL |
stop |
Обычно имеет значение Ctrl+S и в некоторых реализациях может быть изменен пользователем. Используется для временной приостановки записи вывода на терминал. Этот символ особенно полезен при применении старомодных терминалов, так как он может использоваться для того, чтобы приостановить вывод прежде, чем он исчезнет за границей экрана терминала |
start |
Обычно имеет значение Ctrl+Q. Может ли он быть изменен, также зависит от конкретной реализации. Он используется для продолжения вывода, приостановленного при помощи комбинации клавиш Ctrl+S. Если комбинация Ctrl+S не была нажата, то Ctrl+Q игнорируется |
susp |
Если пользователь набирает этот символ, то группе процессов, связанной с терминалом, посылается сигнал SIGTSTP. При этом выполнение группы приоритетных процессов останавливается, и она переводится в фоновый режим. Обычное значение символа suspend равно Ctrl+Z. Его также можно изменить, выполнив команду: $ stty susp <новый_символ> |
можно отменить, набрав перед ними символ обратной косой черты (\). При этом связанная с символом функция не выполняется, и символ посылается программе без изменений. Например, строка
aa\<erase> b <erase> с
приведет к тому, что программе, выполняющей чтение с терминала, будет передана строка аа\<erase> с.