Как стало понятно из предыдущей лекции (Сеанс работы в Linux), основное средство общения с Linux — системная клавиатура и экран монитора, работающий в текстовом режиме. Вводимый пользователем текст немедленно отображается на мониторе соответствующими буквами, однако может и не отображаться, как в случае ввода пароля. Для управления вводом используются некоторые нетекстовые клавиши на клавиатуре: Backspace (он же «Забой») — для удаления последнего введённого символа или Enter — для передачи команды системе. Нажатие на эти клавиши не приводит к отображению символа, вместо этого вводимый текст обрабатывается системой тем или иным способом.
[methody@localhost methody]$ data
-bash: data: command not found
[methody@localhost methody]$ date
Вск Сен 12 13:59:36 MSD 2004
Пример 1. Сообщение об ошибке
Вначале Мефодий ошибся, и вместо команды date
написал data
. В ответ он получил сообщение об ошибке, поскольку такой команды система не понимает. Затем (этого не видно в примере, но случилось именно так!) он снова набрал data
, но вовремя одумался и, нажав клавишу Backspace, удалил последнее «a», вместо которого ввёл «e», превратив data
в date
. Такая команда в системе есть, и на экране возникла текущая дата.
Диалог машины и пользователя неспроста выглядит как обмен текстами. Именно письменную речь используют люди для постановки и описания решения задач в заранее определённом, формализованном виде. Поэтому и задача управления системой может целиком быть представлена и решена в виде формализованного текста — программы. При этом машине отводится роль аккуратного исполнителя этой программы, а человеку — роль автора. Кроме того, человек анализирует текст, получаемый от системы: запрошенную им информацию и т. н. сообщения — текст, описывающий состояние системы в процессе решения задачи (например, сообщение об ошибке «command not found»).
Текстовый принцип работы с машиной позволяет отвлечься от конкретных частей компьютера, вроде системной клавиатуры и видеокарты с монитором, рассматривая единое оконечное устройство, посредством которого пользователь вводит текст и передаёт его системе, а система выводит
необходимые пользователю данные и сообщения. Такое устройство называется терминалом. В общем случае терминал — это точка входа пользователя в систему, обладающая способностью передавать текстовую информацию. Терминалом может быть отдельное внешнее устройство, подключаемое к компьютеру через порт последовательной передачи данных (в персональном компьютере он называется «COM port»). В роли терминала может работать (с некоторой поддержкой со стороны системы) и программа (например, xterm
или ssh
). Наконец, виртуальные консоли Linux — тоже терминалы, только организованные программно с помощью подходящих устройств современного компьютера.
- Терминал
- Устройство последовательного ввода и вывода символьной информации, способное воспринимать часть символов как управляющие для редактирования ввода, посылки сигналов и т. п. Используется для взаимодействия пользователя и системы
Для приёма и передачи текста терминалу достаточно уметь принимать и передавать символы, из которых этот текст состоит. Более того, желательно, чтобы единицей обмена с компьютером был именно один байт (один acsii-символ). Тогда каждая буква, набранная на клавиатуре, может быть передана системе для обработки, если это понадобится. С другой стороны, типичный способ управления системой в Linux — работа в командной строке — требует построчного режима работы, когда набранный текст передаётся компьютеру только после нажатия клавиши Enter (что соответствует символу конца строки). Размер такой строки в байтах предугадать, конечно, нельзя, поэтому терминал, работающий в построчном режиме, ничем, по сути, не отличается от терминала, работающего в посимвольном режиме — за исключением того, что активность системы по обработке приходящих с этого терминала данных падает в несколько раз (обмен ведётся не байтами, а целыми строками).
Свойство терминала передавать только символьную информацию приводит к тому, что некоторые из передаваемых символов должны восприниматься не как текстовые, а как управляющие (например, символы, возвращаемые клавишами Backspace и Enter). На самом деле управляющих символов больше: часть из них предназначены для экстренной передачи команд системе, часть — для редактирования вводимого текста. Многие из этих символов не имеют специальной клавиши на клавиатуре, поэтому их необходимо извлекать с помощью клавиатурного модификатораCtrl.
Команды, подаваемые с клавиатуры с помощью Ctrl, как и символы, передаваемые при этом системе, принято обозначать знаком «^
», после которого следует имя клавиши, нажимаемой вместе с Ctrl: например, одновременное нажатие Ctrl и «a
» обозначается «^A
».
Так, для завершения работы программы cat
, которая считывает построчно данные с клавиатуры и выводит их на терминал, можно воспользоваться командой «^C
» или «^D
»:
[methody@localhost methody]$ cat
Any Text
Any Text
^C
[methody@localhost methody]$ cat
Any Text agaim^[[Dn
Any Text again
^D
[methody@localhost methody]$
Пример 2. Как завершить работу cat
?
Одну строчку вида «Any Tex...» Мефодий вводит с клавиатуры (что отображается на экране), и после того, как Мефодий нажмёт Enter, она немедленно выводится программой cat
(что тоже отображается на экране). С каждой последующей строкой программа cat
поступила бы аналогично, но в примере Мефодий оба раза завершил работу программы, в первом случае нажав «^C
», а во втором — «^D
». Эффект команды оказали одинаковый, а работают они по-разному: «^C
» посылает программе, которая считывает с клавиатуры, сигнал аварийного прекращения работы, а «^D
» сообщает ей, что ввод данных с клавиатуры закончен, можно продолжать работу дальше (поскольку программа cat
больше ничего не делает, она завершается самостоятельно естественным путём). Можно считать, что «^C
» — это сокращение от «Cancel», а «^D
» — от «Done».
В пример не попало, как, набирая первый cat
, Мефодий вновь ошибся и написал ccat
вместо cat
. Чтобы исправить положение, он воспользовался клавишами со стрелочками: с помощью клавиши Стрелка влево подвёл курсор к одному из «c» и нажал Backspace, а затем Enter. В режиме ввода команды это ему удалось, а при передаче данных программе cat
клавиша Стрелка влево не сдвинула курсор, а передала целую последовательность символов: «^[
», «[
» и «D
». Дело в том, что на клавиатуре терминала может быть так много разных нетекстовых клавиш, что на всех них не хватает ограниченного количества разных управляющих символов. Поэтому большинство нетекстовых клавиш возвращают т. н. управляющую последовательность, которая начинается управляющим символом (как правило — Escape
, т. е. «^[
»), за которым следует строго определённое число обычных (для клавиши Стрелка влево — «[
» и «D
»).
То же самое можно сказать и о выводе управляющих последовательностей на терминал. Современный терминал умеет довольно много помимо простого вывода текста: перемещать курсор по всему экрану (чтобы вывести текст там), удалять и вставлять строки на экране, использовать цвет и т. п. Всем этим заведуют управляющие последовательности, которые при выводе на экран терминала не отображаются как текст, а выполняются заранее заданным способом. В некоторых случаях управляющие последовательности, возвращаемые клавишами, совпадают с теми, что управляют поведением терминала. Поэтому-то Мефодий и не увидел «Any Text agaim^[[Dn
» в выдаче cat: «^[[D
» при выводе на терминал перемещает курсор на одну позицию влево, так что было выведено «Any Text agaim
», затем курсор встал прямо над «m
» и поверх него было выведено «n
». Если бы терминал имел вместо дисплея печатающее устройство, в этом месте обнаружилось бы нечто, состоящее из начертаний «m
» и «n
».
Некоторые терминалы умеют и так. Следует ещё иметь в виду, что терминалы разных типов имеют разные управляющие последовательности.
Требования к терминалу как к точке входа пользователя в систему получаются весьма невысокими. Формально говоря, терминал должен удовлетворять трём обязательным требованиям и одному необязательному. Терминал должен уметь:
- передавать текстовые данные от пользователя системе;
- передавать от пользователя системе немногочисленные управляющие команды;
- передавать текстовые данные от системы пользователю;
- (необязательно) интерпретировать некоторые данные, передаваемые от системы пользователю, как управляющие последовательности и соответственно обрабатывать их.
Ограничения на интерфейс напрямую не сказываются на эффективности работы пользователя в системе. Однако чем меньше требований к интерфейсу, тем важнее разумно его организовать. Любое взаимодействие может быть описано с трёх точек зрения: во-первых, какую задачу решает пользователь (что он хочет от системы); во-вторых, как он формулирует задачу в доступном пониманию системы виде; и, в-третьих, какими средствами он пользуется при взаимодействии с системой. В частности, текстовый интерфейс удобно рассмативать с точки зрения предоставляемого им языка общения с машиной: во-первых, описанием этого языка задаётся диапазон решаемых с его помощью задач, а во-вторых, слова этого компьютерного языка (называемые в программировании операторами) предоставляют способ решения пользовательских задач (в виде небольших программ-сценариев). Команды, помогающие пользователю быстро и эффективно обмениваться с машиной предложениями на этом языке, и будут третьей составляющей интерфейса командной строки.