Канонический и неканонический ввод с терминала - PullRequest
37 голосов
/ 11 декабря 2008

Я готовлюсь к экзамену, и меня смущает то, как канонический или неканонический ввод / вывод работает в Unix (например, curses). Я понимаю, что существует буфер, к которому применяются "дисциплины линии" для канонического ввода. Означает ли это, что буфер обойден для неканонического ввода, или это просто означает, что не применяются дисциплины строк? Чем этот процесс отличается для операций ввода и вывода?

В программах curses, с которыми я работал, которые демонстрируют канонический ввод, ввод, вводимый пользователем, вводится автоматически либо после того, как было набрано определенное количество символов, либо прошло определенное время. Считается ли что-либо из этого «дисциплиной в строю» или это нечто совершенно другое?

1 Ответ

76 голосов
/ 11 декабря 2008

для канонического ввода - думаю, оболочка; на самом деле, подумайте о старой доброй оболочке Bourne, так как Bash и ее родственники редактируют из командной строки. Вы вводите строку ввода; если вы допустили ошибку, вы используете символ стирания (по умолчанию Backspace , обычно; иногда Delete ), чтобы стереть предыдущий символ. Если вы запутались полностью, вы можете отменить всю строку символом уничтожения строки (не полностью стандартизировано, часто Control-X ). В некоторых системах вы можете удалить слово с помощью Control-W . Все это канонический вклад. Вся строка собирается и редактируется до конца строки символа & mdash; Возврат & mdash; нажата. После этого вся линия становится доступной для программ ожидания. В зависимости от ожидающих системных вызовов read() вся строка будет доступна для чтения (одним или несколькими вызовами read()).

Для неканонического ввода & mdash; подумайте vi или vim или что-то еще & mdash; Вы нажимаете символ, и он сразу становится доступным для программы. Вы не задерживаетесь, пока не нажмете кнопку возврата. Система не редактирует персонажей; они становятся доступными для программы, как только они набраны. Это зависит от программы, чтобы интерпретировать вещи соответствующим образом. Теперь vim делает ряд вещей, которые немного похожи на канонический ввод. Например, backspace перемещается назад, а в режиме ввода стирает то, что было там. Но это потому, что vim решает заставить его вести себя так.

Канонический и неканонический вывод - гораздо менее серьезный бизнес. Есть несколько различий, связанных с такими вещами, как, например, выводить ли возврат каретки перед переводом строки и делать ли задержки (не обязательно с электроникой; важно в те дни, когда выходное устройство могло быть 110- боди телетайп). Он также может выполнять такие действия, как обработка нечувствительных к регистру устройств вывода & mdash; опять телетайпы. Буквы в нижнем регистре выводятся заглавными буквами, а буквы в верхнем регистре в виде обратной косой черты и заглавных букв.

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


В комментарии TitaniumDecoy спросил:

Итак, при неканоническом вводе входной буфер полностью обойден? Кроме того, где линейные дисциплины входят?

При неканоническом вводе входной буфер все еще используется; если нет программы с вызовом read(), ожидающим ввода от терминала, символы сохраняются во входном буфере. Чего не происходит, так это какого-либо редактирования входного буфера.

Линейные дисциплины - такие вещи, как набор манипуляций, которые выполняет редактирование ввода. Итак, одним из аспектов дисциплины строки является то, что символ стирания стирает предыдущий символ в режиме канонического ввода. Если у вас установлено icase (сопоставление входного регистра), тогда символы верхнего регистра отображаются в нижнем регистре, если перед ними не стоит обратная косая черта; я полагаю, что это дисциплина линии или аспект дисциплины линии


Я забыл упомянуть, что обработка EOF ( Control-D ) обрабатывается в каноническом режиме; на самом деле это означает «сделать накопленный ввод доступным для read()»; если нет накопленного ввода (если вы наберете Control-D в начале строки), то read() вернет нулевые байты, которые затем интерпретируются программами как EOF. Конечно, после этого вы можете весело печатать больше символов на клавиатуре, и программы, которые игнорируют EOF (или работают в неканоническом режиме), будут вполне довольны.

Конечно, в каноническом режиме символы, набранные на клавиатуре, обычно отражаются на экране; Вы можете контролировать, происходит ли это эхо. Тем не менее, это несколько касательно канонического ввода; нормальное редактирование происходит даже при отключенном эхо.

Точно так же сигналы прерывания и выхода являются артефактами обработки канонического режима. Так же как и сигналы управления заданиями, такие как Control-Z , для приостановки текущего процесса и возврата в оболочку. Аналогично, управление потоком ( Control-S , Control-Q для остановки и запуска вывода) обеспечивается каноническим режимом.

Глава 4 Расширенного программирования Unix от Rochkind, 2-е Edn охватывает ввод-вывод терминала и дает большую часть этой информации - и многое другое. Другие книги по программированию для UNIX (по крайней мере, хорошие) также будут освещать это.

...