О блоге

Все новые материалы размещаются на Блогосайте alv.me. Старые - в процессе переноса.

19.08.2008

Заметки о Linux-консоли

2005 г

В этой серии заметок я решил обобщить все, что мне известно о консоли Linux, ее возможностях и настройке.

Содержание

Введение

- Вот за это я и не люблю кошек...
- Может быть, ты просто не умеешь их готовить?
Из нашей любимой рекламы

О том, что такое консоль, написано немало, в том числе и вашим покорным слугой, и распространяться на эту тему не буду. Замечу только, что это сочетание стандартного устройства ввода и стандартного устройства вывода. В случае настольной персоналки (а только о ней и пойдет речь далее) в качестве оных выступают, соответственно, клавиатура и монитор данной конкретной машины (с некоторой долей условности в этот гарнитур можно включить и мышь). Работа в консоли часто отождествляется с использованием текстового режима и интерфейса командной строки. И то, и другое в общем случае не вполне правильно, как и противопоставление консольного режима графическому. Однако это отдельная история, которую я надеюсь затронуть под занавес этого цикла.

Также много (и опять же не без участия автора этих строк) говорилось о несравненных достоинствах консольного режима - его удобстве и эффективности, не говоря уж о недороговизне (с точки зрения ресурсов) и полезности для здоровья (в плане сохранения зрения). Однако многие пользователи, особенно из числа начинающих, по прежнему относятся к текстовой консоли с изрядной долей пренебрежения. Возможно, просто потому, что не умеют ее готовить (пардон, настраивать). А не умеют они это по причине явно недостаточного количества источников информации.

Поэтому в настоящей серии заметок я решил обощить все, что мне известно о настройке Linux-консоли. На труд сей меня подвигла доблесть Ивана Паскаля, создавшего в свое время исчерпывающее (и не устаревшее по сей день) описание системной консоли FreeBSD. С которым, к слову сказать, не вредно ознакомиться и пользователю Linux'а. Дополнительным побуждением явилось то, что в форумах и переписке время от времени всплывают вопросы о том, как изменить, скажем, плотность знаков в консоли, или цвет экранного шрифта.

Конечно, управление консолью во FreeBSD существенно проще и логичнее, чем в Linux'е. Оно сводится, в сущности, к изучению возможностей двух программ - vidcontrol и kbdcontrol. Как нетрудно догадаться из названия, первая отвечает за все, связанное с выводом (то есть настройками экрана), вторая - за все, связанное с вводом (то есть настройками клавиатуры).

В Linux'е ситуация значительно более запутанная. Начать с того, что в различных дистрибутивах штатно используется один из двух сосуществующих пакетов управления консолью - kbd или console-tool. Второй до недавнего времени считался более продвинутым, тогда как kbd рассматривался в качестве устаревшего. Однако нынче они абсолютно равноценны. По ряду причин я определенно тяготею именно к kbd (не в последнюю очередь потому, что и слово короче, и команды в этом пакете - тоже:-)), а потому в первую очередь о нем и буду говорить. Хотя, повторяю, приципиальных ращличий между этими пакетами нет.

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

Далее, служба консольной мыши в Linux'е существенно отличается от аналогичного сервиса FreeBSD (и вообще традиционного для Unix использования этого устройства).

Наконец, в Linux'е все большее признание получает так называемая графическая консоль, поддерживаемая через кадровый буфер видеокарты (так называемый frame buffer). Она предоставляет такое изобилие дополнительных возможностей (вплоть до просмотра видео), которое иначе достижимо только при использовании Иксов (или специализированной библиотеки SVGAlib, не получившей широкого распространения). Почему я и сказал чуть ранее, что в общем случае противопоставление консольного режима графическому неверно.

Обо всех этих темах и пойдет речь в этой серии заметок. Однако, вопреки первой моей фразе, скажу пару слов о том, что же такое консоль.

Что же такое консоль

Как уже было сказано, в случае настольной машины консоль - это сочетание экрана монитора и клавиатуры (мышь пока оставим в покое). То есть некая физическая реалия, правда? Правда, чистая правда, но - не вся правда.

Потому что одно из первых открытий, которое совершал ранее начинаюший линуксоид, - так называемые виртуальные консоли. Помнится, меня на первой фазе знакомства с Linux'ом они просто привели в восторг (каковой не ослабевает и по сей день). Нынче - не то, что давеча: пользователь ну очень дружественного к нему дистрибутива, где по умолчанию устанавливается графический вход в систему, имеет шанс просто не узнать о их существовании...

Виртуальные консоли - это (почти) самостоятельные системы (правда, работающие за счет ресурсов одной и той же машины), в каждой из которых может быть открыт отдельный сеанс работы пользователя (или пользователей - а даже в самой-рассамой персональной Linux-системе их как минимум двое, включая root'а) и запущен совершенно независимый круг задач (включая оконную ситсему X), со своими собственными настройками, наиболее для этого круга подходящими.

По умолчанию в большинстве дистрибутивов Linux активизировано шесть витруальных консолей (во FreeBSD, например, - восемь). Переключение между ними традиционно осуществляется комбинацией клавиш Alt+(F1/F6), клавиша PrtScr перемещает в следующую, после текущей, виртуальную консоль. Кроме того, т.н. Win-клавиши, без которых не обходится ни одна современная "доска", по умолчанию также служат для навигации по виртуальным консолям, позволяя перейти, скажем, к последней использвовшейся, и т.д. - точно не помню, потому что всегда переопределяю их назначение.

Раз уж зашла речь о переопределении - сделаю два маленьких замечания. Во-первых, комбинация Alt+F# для перехода между консолями не являет собой нечто предопределенное божественным промыслом. Ибо зависит исключительно от текущей раскладки клавиатуры, о чем подробнее будет говориться в одной из следующих заметок. Другое дело, что во всех известных мне штатных раскладках для Linux (и FreeBSD) именно эта комбинация задействована под навигацию по консолям (тогда как в раскладках OpenBSD, например, используется комбинация Alt+Control+F#). Но при желании такое положение дел можно изменить (и об этом также речь пойдет впереди) - другой вопрос, нужно ли это делать?

Во-вторых, на некоторых мультимедийных клавиатурах и компактных клавиатурах ноутбучного типа, с которыми мне приходилось сталкиваться, дополнительные win-клавиши категорически отказывались выполнять свои навигационные функции. И вообще, следует помнить, что во всех Unix-системах, вследствие их природной кросс-платформенности, гарантированно однозначно ведут себя только основные алфавитно-цифровые клавиши, прочие же (стрелки управления курсором, клавиши на цифровом блоке, даже Delete и Backspace) в общем случае отнюдь не обязаны выполнять привычные пользователям связки PC-Windows обязанности.

К слову сказать - именно в этом одна из причин неувядающей популярности текстового редактора vi (и его клонов) среди системных администраторов: в какой бы системе своего подшефного зоопарка он ни оказался, его не оставит чувство уверенности в том, что привычные клавиши командного режима (под которые задействована только основная часть "доски") будут всегда вести себя совершенно однозначно.

Однако я отвлекся, вернемся к нашим консолям. Я уже говорил, что каждая виртуальная консоль может рассматриваться как самостоятельная, индивидуально настроенная, система. С оговоркой - "почти". Потому что в том, что касается пользовательских настроек программного уровня, это верно безусловно: авторизовавшись на второй консоли от лица другого пользователя, мы получаем рабочую среду, свойства которой описаны в его пользовательских конфигурационных файлах. Однако что касается собственно свойств консоли - тут существуют многочисленные ограничения.

Одни из свойств консоли (такие, как цвет шрифта и фона) действительно могут быть настроены независимо для каждой виртуальной консоли. Однако самые важные для пользователя характеристики - шрифт и раскладка клавиатуры, - загружаются для всех консолей сразу. Также на все консоли распространяется и карта соответствия (так называемая mapscreen) кодировки ввода (то есть раскладки клавиатуры) и кодировки вывода (то есть экранного шрифта), о чем подробнее будет говориться в заметке о русификации. Хотя (и это важно) карта соответствия не активизуется одновременно с активизацией произвольной виртуальной консоли. Тем не менее, настроить одну консоль на вывод русских текстов в кодировке KOI8-R, другую - в Windows-кодировке, а третью - так вообще в Unicode, без дополнительных ухищрений (о которых я скажу в свое время) не удастся.

Равноценны ли виртуальные консоли? Чтобы ответить на этот вопрос, придется обратиться к истории. Во времена былинные, до рождества PC'ева, существовали так называемые большие машины (mainframe), которые жили своей самостоятельной жизнью в специально отведенных заповедниках, куда пользователям путь был заказан. И общались с ними пользователи посредством так назваемых терминалов - локальных мониторов и клавиатур, не имевших собственных вычислительных ресурсов - все они были сосредоточны в главной машине, предоставлявший их терминалам через последовательные линии связи (но нынешнему, COM-порты). Власть пользователей была ограничена, каждый управлял только своим терминалом, и не имел (теоретически) никакой возможности повлиять на систему в целом.

Однако имелся среди пользователей один умник, который всех напаривал (пардон, всем управлял). Он назывался root-оператором (или просто root'ом), обладал всевластием в масштабе данной системы и реализовывал это всевластие с собственного, всевластного, терминала. Вот этот-то терминал всевластия и назывался консолью в предначальном смысле этого слова.

Казалось бы, консоль - точно такой же терминал, что и любой пользовательский. Однако root, обладая тайным знанием - своим собственным паролем, от которого его всевластие и зависело, мог засадить в систему все хитрости свои, все меры защиты, и все такое. В частности - запрещение авторизоваться root'ом с любого другого терминала, кроме консоли. А для напаривания (опять пардон, управления) пользователями он делал так, чтобы на консоль выводились все системные сообщения (в том числе сообщения об ошибках и информация об авторизации пользователей), почему консоль root'а и получила название системной.

Однако PC уравняла пользователей в правах не хуже известного дивайса полковника Кольта. И хотя даже на персоналке в любой Unix-системе по прежнему имеется всевластный root, в роли его обычно выступает сам пользователь настольной машины, И в его праве предоставить самому себе возможность авторизоваться root'ом или обычным пользователем с любой из виртуальных консолей (случай ущемления прав в домашних многопользовательских системах не рассматриваем, это - дело семейное). Можно организовать даже автоматический беспарольный вход в систему на любой из активизируемых при загрузке консолей.

Другое дело, что и тут можно зарезервировать для целей управления какую-либо одну консоль (запретив с остальных авторизацию root'ом). А также отвести отдельную консоль для вывода системных сообщений и сообщений об ошибках. Однако от рождения все виртуальные консоли равноправны. Несколько "равнее" других только текущая (в данный момент) консоль - именно на нее по умолчанию выводятся системные сообщения (если вообще вывод их не подавлен, как часто делается на настольных машинах). Разумеется, она же служит и для отображения ввода, если не используются специальные приемы перенаправления.

Изначальное равноправие консолей - одно из отличий Linux'а от FreeBSD. В последней первая (называемая также системной) консоль равнее прочих существенно. Правда, для пользователя это ее превосходство оборачивается неудобствами: на нее по умолчанию сыпется куча всякой системной информации. От чего не всегда удается даже перенаправлением ее в устройство /dev/null: например, сообщение о присоединении/отсоединении USB-накопителя окажутся на ней в любом случае.

Еще одно отличие текущей консоли от всех прочих проявляется при запуске с нее какой-либо программы графического режима, например, Иксов (а при этом в первую очередь запускается вполне конкретная программа - X-сервер) или приложений, основанных на библиотеке SVGAlib (последних, правда, немного, кроме знаменитого Doom'а это, пожалуй, только графический вьювер zgv). В этом случае текущая консоль как бы блокируется вплоть до выхода из Иксов (или из SVGAlib-программы). А для запушенной с нее программы активизируется новая виртуальная консоль (об активизации новых консолей - в следующем разделе), перехватывающая на себя и стандартный ввод, и стандартный вывод, то есть становящаяся текущей.

Хотя на самом деле блокировки консоли, с которой запущенны Иксы, не происходит (спасибо Тихону Тарнавскому, обратившему мое внимание на сей факт). Просто она занимается текущим процессом, сиречь Иксами, который и выводит на нее массу своих служебных сообщений. Так что если запустить Иксы в фоновом режиме, а вывод сообщений куда-нибудь перенаправить (в log-файл или тот же /dev/null), то и эту консоль можно задействовать для нормальной работы.

Отключается в Иксах и традиционная клавишная комбинация перехода - Alt+F# (здесь она зарезервирована для собственных целей). Чтобы вернуться в какую-либо из виртуальных консолей, свободную от Иксов, требуется уже три пальца - Alt+Control+F# (не ради ли единообразия в OpenBSD та же комбинация используется для навигации по виртуальным консолям вообще?).

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

Уравнение в правах консоли и терминалов привело к тому, что ныне термины (виртуальная) консоль и (виртуальный) терминал часто выступают в качестве синонимов. И это, товарищи, почти правильно - хотя только для настольных персоналок. И то, следует помнить, что если терминал на PC - всегда виртуален, то консоль имеет и физическое вполощение - монитор и клавиатуру, физически прикрученные к данному системному блоку. Можно сказать, что файл устройства консоли (/dev/console) выступает в качестве реинкарнации активного в данный момент виртуального терминала.

Кроме того, слово терминал служит для обозначения программ эмуляции текстовой консоли с ее командной оболочкой (а в следующем разделе будет показано, что консоль в большинстве случаев тесно сопряжена с шеллом) в графическом режиме оконной системы X. Однако такие программы правильнее так и называть - эмуляторами терминала (а в запущенном виде - терминальными окнами). И вообще, к Linux-консоли они отношения не имеют, да и к Linux'у вообще - лишь косвенное, так как являют собой обычное Иксовое приложение. Речи о них в этих заметках не будет - сл временем я к ним вернусь в разделе про Иксы.

В заключение - несколько номенклатурных замечаний. Как известно, все, что существует в Unix-системе статически - суть файлы, в том числе физические или виртуальные устройства. И консоли тут - не исключение, каждой из них соответствует свой файл в каталоге /dev. Выше упоминалось, что физической консоли соответствует файл /dev/console, имеющий идентификатор группы устройств, так называемый старший (major) номер устройства, равный 5, и идентификатор конкретного устройства, младший (minor) номер, равный 1.

Виртуальные консоли в Linux'е ранее ставились в соответствие файлам вида /dev/tty??, где ?? соответствовал порядковому номеру устройства и мог изменяться в пределах от 0 до 63, хотя в реальности их могло быть меньше. Старший номер всех их был равен 4, младший - был идентичен номеру устройства.

В большинстве современных Linux-дистрибутивов используется так называемая файловая система устройств (devfs), вносящая существенные коррективы в номенклатуру последних. Согласно ей, файлы устройств виртуальных консолей сгруппированы в каталоге /dev/vc/ (в некоторых системах имя каталога, в который монтируется devfs, может быть иным). И именуются они просто своими номерами - /dev/vc/1, dev/vc/2 и так далее, каковые и выступаю заодно в качестве младших номеров устройств (старший номер остается прежним - 4).

Во всех известных мне дистрибутивах, задействующих devfs, используется также демон devfsd, обеспечивающий обратную совместимость с файлами устройств в старой номенклатуре (собственно, дело не только в поддержке старой номенклатуры, но это выходит за рамки сегодняшней темы). И потому в каталоге /dev можно обнаружить и файлы устройств виртуальных консолей типа /dev/tty??. Однако это - лишь символические ссылки на файлы реальных устройств, в чем легко убедиться командой

$ ls -l /dev/tty*

которая выведет список вида

lr-xr-xr-x   1 root root 4 Июн  8  2003 /dev/tty0 -> vc/0
lr-xr-xr-x 1 root root 4 Июн 8 2003 /dev/tty1 -> vc/1
lr-xr-xr-x 1 root root 5 Июн 8 2003 /dev/tty10 -> vc/10
lr-xr-xr-x 1 root root 5 Июн 8 2003 /dev/tty11 -> vc/11

и так далее.

Однако теоретически при использовании devfs наличие файлов устройств старого образца отнюдь не обязательно и зависит от настроек демона devfsd в файле /etc/devfsd.conf. А можно при желании вообще отказаться от обратной совместимости, и тогда никаких tty?? в системе не будет.

Вот и все общие слова, которые я хотел сказать о консолях. А теперь разговор пойдет о том, сколько же их, консолей, бывает в Linux-системе.

Сколько бывает консолей

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

В предыдущей заметке вскользь было упомянуто, что практически во всех современных полнофункциональных дистрибутивах Linux'а при загрузке по умолчанию активизируется шесть виртуальных консолей (кроме Debian - там их, кажется, всего четыре). Однако число это не обусловлено ничем, кроме традиции, и легко может быть изменено в любую сторону.

В отличие от FreeBSD, где максимально возможное число консолей определяется при конфигурировании ядра (и составляет для умолчального ядра GENERIC целых шестнадцать), консоли в Linux'е создаются (до определенного предела) на лету, по мере возникновения в них необходимости. Типичный пример - запуск Иксов (или приложений, использующих SVGAlib). Каждый сеанс Иксов (а командами типа startx -- :# или xinit -- :#, где # - номер Искового дисплея, их можно запустить сколько угодно, вернее, на сколько хватит ресурсов) будет открыт в своей собственной виртуальной консоли, следующей по порядку после уже используемых.

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

За запуск процессов непосредственно после старта системы отвечает процесс init (/sbin/init), являющийся родительским (прямо или косвенно, через запуск пользовательских процессов) по отношению ко всем остальным процессам (во загнул-то! - но подробности в саге о POSIX). А какие конкретно процессы он запускает - определяется его конфигурационным файлом, /etc/inittab.

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

c1:3:respawn:/sbin/agetty 38400 vc/1 linux
c2:3:respawn:/sbin/agetty 38400 vc/2 linux
c3:3:respawn:/sbin/agetty 38400 vc/3 linux
c4:3:respawn:/sbin/agetty 38400 vc/4 linux
c5:3:respawn:/sbin/agetty 38400 vc/5 linux
c6:3:respawn:/sbin/agetty 38400 vc/6 linux

То есть мы видим простую colon-separated таблицу о четырех полях и шести записях. Последнее, как нетрудно догадаться, соответствует "умолчальному" количеству виртуальных консолей. А значение полей - следующие: идентификатор записи, уровень (или уровни) выполнения (runlevels), для которого эта запись имеет силу, акция, выполняемая при этом, и собственно исполняемая команда (в данном случае - команда активизации консоли). Сразу оговорюсь, что в других системах значения всех полей, кроме третьего, могут быть несколько иными (или совсем другими).

Идентификатор записи может в принципе быть любым, единственное требование к нему, как к ID любой базы данных (а перед нами - не что иное, как база данных, хотя и предельно элементарная), - то есть уникальность. В большинстве систем здесь можно видеть просто порядковый номер записи, совпадающий с номером виртуальной консоли. Последнее, впрочем, отнюдь не обязательно (хотя и рекомендуется в документации).

Что такое уровень выполнения - вопрос в данном случае неуместный. Для наших сегодняшних целей достаточно знать, что это то состояние системы, в которое она приходит при нормальной загрузке по умолчанию. В моей системе такое умолчальное состояние достигается при уровне 3, в других здесь может стоять значение любого из доступных уровенй. Так как runlevel 0 соответствует останову системы, runlevel 1 зарезервирован за однопользовательским режимом, когда по определению активизируется только одна виртуальная консоль, а на runlevel 6 происходит перезагрузка системы, то доступными оказываются один из runlevels в диапазоне 2-5 или даже все они - в виде 2345.

Процедуру respawn в третьем поле можно, скорее всего, увидеть в /etc/inittab из любой Linux-системы. Она обеспечивает повторный вызов другого экземпляра того же процесса, который запускается командой из четвертого поля.

Команда же в четвертом поле - это обычно вариации на тему getty, что означает "получение терминала" (get tty). Она вызывает активизацию виртуальной консоли, указанной в качестве аргумента (в нашем примере vc/?) и запуск на ней программы login, обеспечивающей авторизацию пользователя в системе, после чего замешается программой, определенной в качестве его командной оболочки по умолчанию (login shell). Причем все эти программы (getty, login, пользовательский login shell) выполняются внутри одного и того же процесса (подробности - в соответствующем разделе).

Завершение пользовательского сеанса работы приводит к смерти этого процесса, однако не вызывает деактивизации данной виртуальной консоли, так как процедура respawn обеспечивает "регенерацию" процесса getty с повторным вызовом программы login и (в случае авторизации) login shell. То есть всем определенным в /etc/inittab виртуальным консолям суждена вечная (до останова или переазгрузки системы) жизнь.

Еще несколько замечаний о содержимом четвертого поля. В приведенном примере использована команда /sbin/agetty (из пакета util-linux). Полный путь к ней указан не случайно - очевидно, что файл /etc/inittab задействуется системой раньше, чем считывается значение переменной $PATH из общесистемного или пользовательского профильного файла (типа /etc/profile или ~/.profile. Однако сама по себе команда получения терминала в других системах может быть иной - например, /sbin/mingetty или что-нибудь подобное.

Первый аргумент команды обозначает скорость соединения по последовательной линии. Очевидно, что для виртуальной консоли никакого физического смысла он не имеет и спокойно мог бы быть опущен, что обычно и делается при использовании программы /sbin/mingetty (что и не удивительно, так как mingetty и приспособлена только для работы с вирутальными терминалами). Однако в /sbin/agetty попытка удалить этот аргумент приводит к ошибке (и, соответственно, невозможности загрузки). Так что лучше придерживаться той формы вызова getty, которая принята в вашем дистрибутиве.

Следующий аргумент - файл устройства активизируемой виртуальной консоли. При использовании devfs обязательно давать его именно в новой номенклатуре, вне зависимости от настроек демона devfsd (которые также вступают в силу уже после считывания /etc/inittab). Если devfs не используется, значение этого аргумента будет - tty1, tty2 и так далее.

Обращаю внимание, что в приведенном примере полный путь к файлу устройства не используется - команда agetty автоматически добавляет к нему префикс /dev/. Однако при использовании других команд получения терминала полный путь может потребоваться.

Наконец, последний аргумент определяет тип "получаемого" командой gettyтерминала (в примере - стандартная linux-консоль). Он также не обязателен, однако дан мной для пущей определенности (да и вреда от него никакого). Кроме того, насколько я понимаю, указание типа обязательно, если в linux-консоли должен эмулироваться терминал какого-либо иного типа (вроде vt100 или vt220).

Теперь, зная, как описываются "изначальные" виртуальные консоли, легко догадаться, как изменить их количество. Для уменьшения оного (что несколько сэкономит ресурсы слабой машины) достаточно удалить (или закомментировать) соответствующее число строк. А для увеличения - создать должное количество новых по образу и подобию существующих, изменяя только идентификатор и имя файла устройств:

c7:2:respawn:/sbin/agetty 38400 vc/7 linux
c8:2:respawn:/sbin/agetty 38400 vc/8 linux

и так далее, вплоть до

c63:2:respawn:/sbin/agetty 38400 vc/63 linux

Ибо 63 - это максимально возможное количество виртуальных консолей. Обусловлено оно тем, что именно столько младших номеров ранее (до внедрения devfs) резервировалось за устройствами этого класса. Файловая система устройств сняла, как-будто бы, проблему их старших и младших номеров. Однако мне не удалось найти информации о том, можно ли при этом увеличить количество виртуальных консолей сверх приведенного скромного:-) числа. Исходя из соображений обратной совместимости (да и здравого смысла:-)) - вряд ли.

Заодно замечу, что сказанного достаточно только при использовании devfs. Если она не задействована, то нет гарантии, что файлы устройств tty7 и выше реально имеются в каталоге /dev. И тогда их нужно будет создать - с помощью специально к тому предназначенного сценария /dev/MAKEDEV или непосредственно командой mknod. В первом случае достаточно перейти в каталог /dev и запустить

$ ./MAKEDEV -v tty7

ответом на что будет сообщение типа

create tty7 c 4 7 root:tty 666

знаменующее успех предприятия. Если же последует сообщение об ошибке (например, потому, что создание такого устройства не предусмотрено конкретным вариантом сценария MAKEDEV), придется обратиться к команде mknod, требующей указания типа устройства, старшего и младшего номеров, а также прав доступа - за деталями отправляю к man (8) mknod.

А мы тем временем вернемся к истинно толстовскому вопросу: сколько же виртуальных консолей человеку надо? Ответ на него зависит в первую очередь от преобладающей рабочей среды того человека - Иксы ли это или все-таки консоль.

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

А вот если стиль работы - преимущественно консольный, возможны варианты. Можно развести виртуальных консолей практически под каждую возможную задачу, и тогда 8-10 штук - вполне реально будут востребованы. До недавнего времени я придерживался именно такого подхода. И число консолей у меня иногда доходило до 11. Что требовало выработки четкой системы - какие задачи на каких консолях запускаются. А главное - неукоснительно этой системы придерживаться.

Для примера, моя система до недавнего времени была такова (это не пример для подражания, а просто возможный образец). Вне зависимости от числа консолей, последняя из них предназначается исключительно для запуска Иксов, а предпоследняя - для авторизации (при необходимости) в качестве root'а. Первые четыре консоли, напротив, служат для повседневной работы: на первой я пишу, на второй - смотрю ранее написанные тексты по теме (из которых надергиваю фрагменты с помощью мыши), на третьей запущен браузер (links), четвертая зарезервирована для выполнения необходимызх команд и (или) просмотра man-страниц.

Когда эта система окончательно устаканилась (а главное, следование ей дошло до рефлекторного уровня), я обнаружил, что перманентно мне довольно шести умолчальных консолей - четырех рабочих, одной для потенциального root'а и одной для Иксов. А необходимость в дополнительных терминалах возникает лишь время от времени, для кое-каких разовых акций (в основном копирования/перемещения файлов или просмотра каталогов). Или, напротив, для протяженного, но не требующего вмешательства, процесса, типа проигрывания mpeg-файлов (программой mpg321). И вот тут-то настало время вспомнить о возможности Linux'а (в отличие от FreeBSD) создавать виртуальные консоли на лету, для запуска конкретного процесса.

Очевидный способ открыть новую виртуальную консоль - запустить ту же программу из семейства getty, которая используется для инициации консолей умолчальных, например

$ agetty 38400 vc/9 login

Однако по ряду причин способ этот - не самый удобный. Тем более, что в пакете kbd цели открытия новых консолей служит штатная команда openvt (вероятно, и в console-tools существует аналогичное средство, уже не помню). Она имеет изрядное количество опций (о которых - см. man openvt), однако необходим ей лишь единственный аргумент - имя команды, которая будет исполнена на вновь активизированной консоли (при необходимости для этой команды не возбраняются собственные опции и аргументы). Так, в форме

$ openvt /bin/zsh

она активизирует ближайшую незадействованную консоль (например, 7-ю) и запустит на ней экземляр командной оболочки Z-Shell, команда

$ openvt login

выведет на следующей (скажем, 8-й) консоли предложение авторизоваться. А команда

$ openvt -l user_name

запустит (в данном примере - на 9-й консоли) сеанс работы именованного пользователя (с его командной оболочкой и всеми профильными настройками).

Номер активизируемой консоли можно задать явно, с помощью опции -c. То есть команда

$ openvt -c 63 mpg321 /path/*.mp3

начнет проигрывать на самой дальней консоли все mpeg-файлы из указанного каталога.

При открытии новой виртуальной консоли следует иметь ввиду, что она не будет полностью идентична по своим свойствам консолям "умолчальным". В частности, на нее автоматически не будет выведена "магическая последовательность", обеспечивающая активизацию так называемой карты соответствия (mapscreen), преобразующей кодировку клавиатурного ввода в кодировку экранного вывода. И потому, в случае стандартной для Linux русификации системы (ввод - KOI8, вывод - CP866) просмотреть в ней кириллическоий текст не удастся. Хотя и раскладка клавиатуры нашей новой консоли, и экранный ее шрифт будут вполне кириллическими. Впрочем, активизировать на ней mapscreen можно и вручную, но этому будет посвящена специальная заметка.

Во всех приведенных примерах текущей остается консоль, с которой была дана команда openvt (она назвается также управляющей консолью - это понятие нам потребуется в проследующих заметках). Чтобы одновременно с запуском процесса переключиться на консоль новообразованную, требуется опция -s. Однако и в том, и в другом случае в консоли, с которой запускалась команда openvt, возвращается приглашение командной строки, и в ней можно продолжать нормально работать. Хотя возможность эту можно и блокировать - с помощью опции -w командная строка в текущей (для openvt) консоли становится недоступной до завершения исполнения команды в консоли новообразованной.

Деактивация новообразованной консоли происходит либо естественным образом, по завершении запущенного на ней процесса (пример с запуском mpeg-проигрывателя), либо по принудительному выходу из работающей здесь программы (в примере с zsh и login - с помощью команды exit, а во втором случае также и logout). Если команда openvt была дана с опцией -w, то есть блокировкой управляющей консоли, то из нее можно и прервать запущенный процесс - обычной клавишной комбинацией Control+C. При этом в примере с login никакой регенерации приглашения авторизоваться не происходит за отсутствием акции respawn.

Деактивированная тем или иным образом консоль как бы продолжает существоввать. То есть в нее можно перейти и даже посмотреть на остатки вывода выполнявшихся команд (хотя делать в ней, разумеется, ничего нельзя без повторной активации той же командой openvt). Для полного искоренения такой полуживой консоли предназначена специальная команда - deallocvt. В качестве аргументов ее выступают номера консолей, подлежащих окончательному истреблению. Без аргументов же она уничтожит все деактивированные консоли, то есть те, на которых в данный момент не исполняется никакого процесса. Разумеется, консолей умолчальных она не затронет - ведь на них в любом случае запущен процесс getty и порожденная им команда login.

Открывая консоли на лету, легко увлечься и перевалить за те 12, которые доступны по комбинации клавиш Alt+F# (к слову, количество активизированных консолей в данный момент можно посмотреть с помощью команды fgconsole). Как же получить доступ к этому консольному изобилию?

Во-первых, как уже говорилось, с помощью клавиши PrintScreen в большинстве случаев можно как бы "пролистать" активизированные консоли, начиная с первой. Что, конечно, скучно, если требуется быстрый переход в консоль за номером 13... Во-вторых, доступ к консолям с 13-й по 24-ю обычно возможен по комбинации клавиш Alt+Shift+F#. Однако, как уже было сказано ранее, оба эти способа возможны не всегда, так как зависят и от раскладки клавиатуры, и от ее типа. И к тому же не обеспечивают перехода на консоли с 25-й по 63-ю, буде таковые все же понадобятся.

К счастью, на такой чрезвычайный случай есть специальная, и очень простая, команда, не зависящая ни от чего -

$ chvt #

которая мгновенно перенесет нас в ту консоль, номер которой указан в качестве ее аргумента...

Открывать консоли с помощью команды openvt доступно только для root'а - это определяется правами доступа к файлам устройств неактивизированных консолей, хозяином которых является суперпользователь (активированная же консоль меняет хозяина на того пользователя, который в ней авторизовался). Поэтому любой запущенный на такой новообразованной консоли процесс также будет выполняться от лица администратора (если, конечно, это не процесс login с последующим входом в систему обычного пользователя). Такое положение не всегда желательно с точки зрения безопасности. Избежать же его можно с помощью иного способа активизации консолей, о котором сейчас и пойдет речь.

Вопросы автоматизации

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

Напрашивающееся решение - беспарольный вход в систему, - отнюдь не идеально. Во-первых, это вопиющее нарушение правил техники безопасности. Конечно, на локальной машине ими можно бы принебречь - все равно, доступ к ней легко получить, загрузившись с любого сменного носителя. Но уже при модемном подключении к Сети и динамическом IP-адресе беспарольный вход очень не рекомендуется. Главное же, он не избавляет от необходимости ввода пользовательского имени, то есть техника безопасности не только нарушается, но и нарушается неоправданно.

И потому были придуманы различные способы автоматизации входа в систему, то есть - автоматической регистрации пользователя в момент активации виртуальной консоли. Они работают вне зависимости от того, открывается ли консоль в момент старта системы или на лету в ходе дальнейшей работы. При этом сами по себе учетные записи пользователей (в том числе и их пароли) остаются в неприкосновенности, и потому удаленный доступ к данной машине все равно требует ввода регистрационных данных.

Несколько таких методов автоматизации входа рассмотрены в статье Адриана Чанга (имеющейся в русском переводе). В ней упомянуты патч к программе mingetty и пакет autologin, а также предложена автоматизация методом "правки напильником". Он основан на использовании опции -l программ семейства getty, которая позволяет подменить выполняемую по умолчанию команду login какой-либо альтернативной. В качестве такой альтернативы предложена простенькая Си-программа, выполняющая все ту же команду login в форме

$ login -f user_name

с предварительной аутентификацией указанного пользователя.

Метод этот не показался мне удобным. Во-первых, при необходимости регистрации более чем одного пользователя потребуется создавать (и компилировать) по экземпляру такой программы на каждого из них. Во-вторых (и главных), он у меня просто не сработал - стадия аутентификации действительно пропускалась, но пароль на вход запрашивался все равно (кстати, в man (1) login я не нашел никаких указаний на то, что опция -f освобождает от ввода пароля).

Интуитивно понятно, что проблема автоматической идентификации пользователей может быть решена каким-либо скриптовым методом. И я было занялся сочинением такого скрипта, когда благодаря статье Владимира Попова наткнулся на Perl-сценарий qlogin, специально для того и предназначенный. И к тому же подробно описанный в статье его автора - Брайана Хендерсона.

Установка его очень проста - достаточно распаковать архив и скопировать исполняемый сценарий (qlogin) в подходящее место (а подходящим для такого рода программ по понятным причинам является каталог /sbin). Также неплохо поместить и его man-страницу (qlogin.1) куда следует (у меня в системе - в /usr/man/man1), поскольку в ней содержится исчерпывающая информация по применению этого скрипта.

Правда, дополнительно требуется еще и установить два Perl-расширения. Первое, в соответствие с документацией (~/qlogin/README) находим в подкаталоге path_to_src/qlogin/setgroups, перейдя в который, выполняем

perl Makefile.PL
make
make install

для помещения в должное место (по умолчанию - в /usr/lib/perl5/5.X.X/i686-linux/). Второе расширение относится к методу контроля за авторизацией, использующему файлы /etc/utmp и /etc/wtmp. В моей системе таковые отсутствуют за ненадобностью, и к тому же само расширение следовало еще скачать с http://cpan.org. Однако без него вполне можно обойтисть, для чего оказалось достаточно из текста qlogin удалить строки, имеющие отношение к utmp.

Скрипт qlogin в равной мере пригоден как для интерактивной активизации консолей "на лету" (выступая как замена команды openvt), так и для автоматической регистрации на них при старте системы (то есть для подмены программ семейства getty). При использовании qlogin во втором качестве автор настоятельно рекомендует предварительно "потренироваться в тряпичный" - то есть запустить его с нужными опциями и аргументами из командной строки. Помня при этом, что управляющим терминалом для qlogin будет та виртуальная консоль, с которой он был запущен.

Аргументов для команды qlogin, вне заивисимости от способа ее применения, требуется два - имя файла целевой консоли и имя пользователя:

$ qlogin /dev/vc/# user_name

Обращаю внимание, что имя файла устройства, в отличие от команды agetty, должно сопровождаться полным путем (как в моем примере).

Из опций qlogin (напомню, что их вдоволь можно найти в man-странице) наиболее важна --command, значением которой будет имя команды, запускаемой на новой консоли вслед за ее открытием и автоидентификацией пользователя. При необходимости команда может сопровождаться собственными опциями и агрументами:

$ qlogin /dev/vc/# user_name \
--command="command [options] [arguments]"

При этом очевидно, что для экранирования пробелов в этом случае должны использоваться двойные, то есть не строгие, кавычки. Полный путь к исполняемого файлу команды при интерактивном запуске qlogin не обязателен (если, конечно, путь этот описан в переменной окружения $PATH).

Очевидно, что интерактивный запуск qlogin возможен только от лица root'а, поскольку ни один обычный пользователь не имеет соответствующих прав доступа к файлам устройств неактивизированных виртуальных консолей.

Для автоматической регистрации пользователей при старте системы вызов команды qlogin следует поместить в файл /etc/inittab вместо команды getty. Например, если мы хотим на первой виртуальной консоли автоматически авторизовать некоего пользователя "имя рек", следует изменить первую строку секции описания виртуальных консолей таким образом:

c1:2:respawn:/sbin/qlogin /dev/vc/1 имя_рек

Повторяю, указание полного пути к файлу устройства при этом обязательно, иначе init, не обнаружив оного, впадет посредством акции respawn в пятиминутный цикл перезапуска процесса qlogin.

Опции команды qlogin можно использовать и при вызове ее из файла /etc/inittab. Так, благодаря строке

c1:2:respawn:/sbin/qlogin /dev/vc/1 имя_рек \
--command="/bin/tcsh -l"

при старте системы на первой виртуальной консли будет не только зарегистрирован пользователь "имя рек", но для него в качестве login shell загрузится командная оболочка tcsh вместо той, что предписана ему по умолчанию (например, bash). А строка вроде

c6:2:respawn:/sbin/qlogin /dev/vc/6 имя_рек \
--command=/usr/bin/top

обеспечит на шестой консоли вывод программы top для контроля над запущенными процессами.

Следует только помнить, что вызов какой-либо программы как опции команды qlogin при этом происходит до считывания каких-либо пользовательских (и многих общесистемных) профильных файлов. Из чего следует, во-первых, необходимость указания полного пути к исполняемому файлу вызываемой программы (как в примере) - ведь переменная $PATH еще не определена. А во-вторых, сложные программы, зависящие от многих конфигурационных файлов, запустить как опцию команды qlogin не удастся. Так, моя попытка автоматом грузить на 6-й консоли Инксы "в лоб", с помощью опции вида --command="/usr/X11/bin/startx" успехом не увенчалась, вызвав только поток сообщений об отсутствии файлов типа xinit, xautority и т.д. Вероятно, задача эта решаема, но как - пока руки не дошли...

И еще следует помнить, что консоль, на которой через /etc/inittab и qlogin запущена какая-либо программа, уже не удастся использовать для иных целей: попытка выйти из программы top (в приведенном выше примере) приведет, благодаря акции respawn, к перезапуску qlogin и, через его опцию, нового экземпляра той же программы top.

Таким образом, мы обеспечили себя достаточным количеством виртуальных консолей и удобным способом доступа к ним. Теперь посмотрим, как создать в единичной консоли максимальный комфорт для практической работы. Задача эта распадается на две части - комфорт при выводе и комфорт при вводе. Поскольку глаз у нас всего двое, и больше уже не будет (а руки на худой конец можно заменить протезами), начнем с вывода.

Прорубить окно в систему

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

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

В то же время, если блоки для копирования и вставки выделять средствами текстового редактора (в joe, например, этой цели служат команды Control+K-B для начала и Control+K-K - для конца выделения блока. В этом случае мы, действуя клавишами управления курсором (или такими командами Joe, как Control+F, Control+B, Control+P, Control+N), как бы протаскиваем наш текст через прорезь экрана. Подобно тому, как детский диафильм стародавних времен для своего воспроизведения протаскивалася через соответствующий агрегат (кто не помнит - назвался он диапроектором). Правда, в случае с экранным буфером такое протаскивание возможно как по вертикали, так и по горизонтали.

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

Поскольку сам по себе размер экрана - объективная реальность, данная нам в дюймах его диагонали (да и то, в случае CRT-мониторов, с обманом), напрашивается решение - поместить на экран как можно больше информации. То есть - увеличить разрешение.

Термин "разрешение" применительно к текстовому режиму используется в несколько ином (и достаточно условном) смысле, чем в графических системах типа Иксов или MS Windows. Ведь в качестве единицы измерения ширины и высоты экрана здесь выступает не пиксель, а их набор (матрица), составляющий единичный символ. И потому правильнее говорить не о разрешении экрана текстовой консоли, а о плотности символов на ней.

Это повелось со стародавних времен чисто текстовых мониторов и видеоадаптеров, когда на экране могли воспроизводиться только цельные символы, выдаваемые знакогенератором видеоподсистемы из неких фиксированных их наборов, как бы "вшитых" в нее. Однако уже давно видеокарты приобрели способность подгружать (и выводить на экран) и разные другие наборы символов, считываемые из соответствующих шрифтовых файлов. Вот этим-то свойством мы и воспользуемся для расширения нашего поля зрения.

Стандартная плотность символов текстовой консоли в Linux, устанавливаемая по умолчанию, составляет 80 колонок на 25 строк (80x25). И обеспечивается она использованием шрифта с матрицей 8 на 16 пикселей. В имени такого шрифтового файла, вне зависимости от всего прочего (собственно наименования, кодировки и т.д.) всегда будут присутствовать такие цифры - 8x16. То есть, казалось бы, для увеличения "разрешения" текстовой консоли достаточно было бы подгрузить шрифт с иной матрицей символов. Однако это не совсем так.

Начать с того, все консольные шрифты, говоря типографскими терминами, не пропорциональные, а моноширинные (то есть ширина буквы "л" в пикселях точно такая же, как и ширина буквы "щ"). Далее, ширина символьной матрицы - фиксированная для любых шрифтов, и составляет 8 пикселей. Это обусловлено аппаратными особенностями видеосистемы тех компьютеров, которые в старое время называли IBM PC-совместимыми (а нынче кличут просто PC или писюками - это те самые машины, за которыми мы с вами и сидим). В них под ширину символа отведено 9 пикселей, причем последний, 9-й, зарезервирован на тот случай, чтобы между символами на экране всегда оставались пробелы, даже между буквами типа "н" и "м" (то есть теми, у которых полностью заняты первая и посленяя колонки матрицы). И, следовательно, заменяя шрифт с матрицей 8x16 на более мелкий (а стандартно в любом дистрибутиве можно найти еше и шрифты с матрицами 8x14 и 8x8 для любых кодировок, для некоторых же наборов символов доступны высоты матрицы 19, 12, 10, 9, 7 и 6 пикселей), мы увеличиваем лишь количество строк, отображаемых на экране, при сохранении количества символов в строке.

Забегая вперед, отмечу, что в Linux-консоли возможно использование шрифтов с количеством строк матрицы, отличным от 8. Но - только в режиме графической консоли, который будет предметом финальных заметок цикла.

Тем не менее, в некоторых случаях этого может оказаться достаточно. И на сей предмет к пакете kbd есть специальная команда - setfont (в console-tools ей соответствует consolechars; длина последней - одна из причин моей нелюбви к этому пакету)). Она требует единственного обязательного аргумента - имени подгружаемого шрифтового файла. То есть в форме

$ setfont cp866-8x8

мы загрузим шрифт в кодировке CP866 и с матрицей символов 8x8, в результате чего плотность строк у нас возрастет более чем вдвое (до примерно 55-56) по сравнению с "умолчальной". Вид экрана, правда, при этом будет вполне отвратительным. И потому "расширение окна" таким образом - лишь временное решение проблемы.

Второй вариант увеличения плотности символов на экране консоли - команда resizecons из все того же пакета kbd (есть она, кажется, под тем же именем, и в пакете console-tools). Смысл ее понятен из название - это именно масштабирование консольного дисплея, то бишь изменение количества отображаемых строк и колонок. Она может быть использована в трех формах:

$ resizecons COLSxLINES

или

$ resizecons COLS LINES

а также

$ resizecons -l LINES

где под COLS и LINES понимается количество знаков в строке и количество строк, соответственно.

Использование команды resizecons сопряжено с рядом ограничений. Во-первых, ни количество строк, ни количество колонок не могут быть произвольными числами. Они должны соответствовать фиксированным сочетаниям, поддерживаемым, с одной стороны, ядром Linux, с другой - наличной видеокартой. Теоретически (то есть ядром) поддерживаются значения плотности строк - 25, 28, 30, 34, 36, 40, 44, 50, 60, и плотности знаков в строке - 80, 100, 132 (детали можно посмотреть в файле документации к ядру - /usr/src/linux/Documentation/svga.txt). Однако практически достижимы лишь некоторые сочетания этих значений. Далее в этой заметке я расскажу, как определить значения плотности символов, пригодные именно для данной системы.

Второе ограничение связано с используемыми шрифтами. Дело в том, что команда resizecons, если так можно выразиться, синтетическая, и выполняет несколько последовательных действий. Из которых финальным является смена текущего экранного шрифта тем, который имеет соответствующую плотности строк высоту матрицы (обычно 12 пикселей для 28-30 строк и 8 или 9 - для большего их числа). А имя этого шрифта, как нетрудно догадаться - default, и ни малейшей кириллицы он не содержит. То есть при необходимости работы с русскими текстами вслед за изменением "разрешения" экрана необходимо и переопределить шрифт на соответствующий кириллический.

И наконец (хотя, вероятно, с этого следовало бы начать), в некоторых системах команда resizecons просто отказывается работать, выдавая сообщение о невозможности найти файл указанного видеорежима.

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

Для выполнения этого действа неолбходимо, во-первых, иметь должным образом собранное ядро. То есть в пункте его конфигурации Console drivers (при использовании make menuconfig), кроме опции VGA text console (она обязательна в любом случае, кроме встраивания в ядро поддержки Frame Buffer, о чем пойдет речь в заключительных заметках цикла), необходимо включить и опцию Video mode selection support.

Далее, необходимо на стадии загрузки передать ядру параметр vga=значение. Это можно сделать вручную в ответ на приглашение boot при использовании Lilo или включив режим редактирования загрузочной записи, если в качестве загрузчика выступает GRUB. А можно и назначить какой-либо видеорежим загружаемым по умолчанию. В GRUB для этого следует дописать в строку его конфигурационного файла /boot/grub/menu.lst, определяющуюю образ ядра и устройство корневой файловой системы

kernel /bzImage root=/dev/hda?

параметр vga=значение. Например, если придать этой строке вид

kernel /bzImage root=/dev/hda? vga=5

по умолчанию будет загружаться видеорежим с плотностью знаков 80x34. В Lilo той же цели послужит строка

vga=5

добавленная в любое место Linux-секции файла /etc/lilo.conf после строки, определяющей загрузочное устройство (детали - в документации по Lilo, я его основательно подзабыл, так как давно не пользуюсь).

В третьих, и это главное, следует выяснить, какие видеорежимы практически доступны в конкретной системе (напомню, что теоретически доступные режимы перечислены в файле /usr/src/linux/Documentation/svga.txt), и какие из них выглядят подходящими с точки зрения информативности и зрительного восприятия. Для этого нужно провести небольшое исследование с помощью передачи ядру параметра vga=ask (любым из упомянутых выше способов). В этом случае перед загрузкой ядра Linux будет выведено предложение просмотреть (нажав клавишу Enter) список доступных видеорежимов в виде вроде следующего:

0 0F00  80x25
1 0F01 80x50
...

и так далее. Чтобы убедиться, что список этот полон, можно дать команду scan, которая проведет повторный мониторинг возможностей видеокарты (при этом может создасться впечатление, что система пошла на перезагрузку; впрочем, и мертвое зависание в этой ситуации случается) и выведет тот же (или расширенный) список повторно. Чтобы загрузиться в любом из доступных режимов, нужно ввести его номер, шестнадцатеричный (из первой колонки) или восьмеричный (из второй). А перепробовав все режимы, которые кажутся разумными, увековечить его вышеописанным способом в конфигурационном файле Lilo или GRUB.

Параметр vga может принимать и другие значения, например, normal (режим 80x25, что эквивалентно отсутствию параметра vga) или extended (в этом случае загружается какой-нибудь из режимов с большей плотностью строк, какой именно - предсказывать не берусь, скорее всего - что-то вроде 80x50). А при использовании Frame Buffer к списку добавится еще много режимов для графической консоли, но об этом речь впереди.

Загрузка ядра в выбранном видеорежиме через параметр vga никак не влияет на определение экранного шрифта по умолчанию, так как последний будет загружен далее по ходу старта машины при обработке одного из сценариев инициализации (например, /etc/rc.local). Изменение шрифта с "умолчального" на переопределенный можно зримо наблюдать на последней стадии загрузки, почти прямо перед появлением приглашения к авторизации (или - приглашения командной строки, если был выбран описанный ранее способ автоидентификации пользователя). И потому установка видеорежима через параметр ядра не накладывает на выбранный шрифт никаких ограничений. Так, даже использование плотности символов 132x60 ничуть не препятствует назначению умолчальным шрифта с матрицей 8x16..

Но прежде - несколько слов о еще одном способе доступа через виртуальную консоль, осуществляемом через экранную память консоли (console screen memory), которая во FreeBSD удачно называется буфером истории (history buffer - не путать с историей команд, доступ к которой осуществляется средствами шелла). Это - расширение стандартного экранного буфера, позволяющее (по нажатию комбинации Shift+PgUp/PgDown) "пролистать" назад (и вперед - вплоть до текущего) несколько экранов и при помощи мыши вытащить на текущий экран (или другую виртуальную консоль) экранный блок из любого доступного места.

Правда, в Linux доступ к буферу экранной истории более ограничен, чем во FreeBSD. Поскольку первое же переключение на другую виртуальную консоль подменяет его содержимое, и при обратном переключении доступ к истории именно этой консоли становится невозможным (во FreeBSD каждая из виртуальных консолей имеет собственный буфер истории, и получиьть к нему доступ можно в любой момент, нажав клавишу ScrollLock, после чего клавиши типа PgUp/PgDown и стрелки управления курсором уже не перемещают этот самый курсор по текущему экрану, а служат для перемещения по экранам и строкам из буфера истории, соответственно).

И еще о буфере экрана. Как и всякое историческое явление, текущее его содержание можно сохранить для потомков. В виде, принятом в Unix - то есть в виде файла. Делается это командой setterm из пакета util-linux (запомним ее, она применяется и для других целей. Из-за своего многоцелевого назначения команда эта имеет множество опций, с которыми можно ознакомиться через man (1) setterm. Однако в сегодняшнем контексте нас интересуют только следующие: dump, append и file.

Команда

$ setterm -dump

создает "слепок" буфера текущей виртуальной консоли в виде простого текстового файла с именем по умолчанию - screen.dump. В качестве ее аргумента можно использовать номер консоли, для которой требуется сделать дамп. А добавление опции -file имя_файла перенаправит этот дамп в файл с указанным именем. Опция же -append присоединит новый дамп к уже существующему файлу - "умолчальному" screen.dump или поименованному опцией -file.

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

И тут поневоле приходит на память FreeBSD, где существует утилита scr2png, именно для этой цели и предназначенная. Она принимает на ввод текстовый экранный дамп (создаваемый во Free командой vidcontrol) и преобразует его в графический файл формата PNG, используя информацию об экранном шрифте, данную в виде соответствующей опции. То есть в результате мы получаем графический снимок именно текстовой консоли, идентичный наблюдаемому, причем - очень высокого качества. Не взялся ли кто-нибудь за написание аналогичной программы для Linux'а?

А пока Linux-программеры размышляют на эту тему, мы перейдем к следующему вопросу - украшению консоли, что будет темой следующей заметки.

Украшение консоли

По мне так текстовая консоль Linux прекрасна сама по себе, в первозданном виде по умолчанию: белые или светло-серые буквы на радикально черном фоне строги, но элегантны. Разумеется, при одном непременном условии - выборе подходящего шрифта.

Кажется, одна из причин того, что многие пользователи пренебрегают консольным режимом, именно в шрифтах и кроется. Действительно, тот, с позволения сказать, шрифт, который обычно устанавливается в консоли по умолчанию при ее кириллизации, - отнюдь не верх эстетического совершенства. Однако ограничиваться "умолчальным" шрифтом никто не заставляет.

Благо, экранных шрифтов для консоли в современных Linux-дистрибутивах обычно много. В этом можно убедиться, просмотрев каталог типа /usr/share/kbd/consolefonts или тот, где они содержатся в конкретном дистрибутиве (точное местоположение легко определить командой find со значением consolefonts для опции -name). Вывод команды ls для этого каталога займет уж точно пару экранов. И шрифтовые файлы, которые в нем можно увидеть, обычно (хотя и не обязательно) имеют вид *.psf.gz (то есть использующие сигнатуру psf и сжатые утилитой компрессии gzip, хотя последнее не всегда применяется). Кроме этого, в последнее время в дистрибутивах всречается все больше шрифтов вида *.psfu (psfu.gz). А иногда можно обнаружить и файлы без всякого суфикса (типа alt8x16).

В чем различие между ними? Файлы без суфикса - это шрифты в т.н. raw-формате, то есть содержашие только собственно данные о шрифте, без всякой дополнительной информации (именно такие шрифты используются в консоли FreeBSD). Файлы же с суфиксом psf, кроме шрифтовых данных, содержат еще т.н. psf-сигнатуру, в которой описываются свойства шрифта. И, наконец, в файлы вида psfu дополнительно вкючается еще и таблица screen font map (sfm), преобразующую внутренние коды символов в коды экранного шрифта.

Почему так сложно? Дело в том, что консольный драйвер Linux (в отличие от syscons той же FreeBSD), способен функционировать в двух режимах - 8- и 16-битном. В первом, как можно догадаться из названия, все символы, как на вводе, так и на выводе, передаются в восьмиразрядном виде - это те самые навязшие в зубах кодировки Великого и Могучего. И, соответственно, каждый вводимый (с клавиатуры или из файла) символ напрямую транслируется в свое экранное представление.

В 16-битном режиме консольный драйвер внутри себя оперирует 16-ти же разрядным представлением символов, то есть кодировкой Unicode. И здесь возможны два варианта: а) 16-битное представление ввода и вывода (т.н. собственно Unicode-режим) и преобразование ввода во внутреннюю кодировку драйвера и вывода - в обратном направлении.

О собственно Unicode-режиме я говорить пока не буду: по ряду причин он только-только начинает приживаться в консоли, и это будет темой одной из ближайших заметок.

Шестнадцатибитный же режим с трансляцией до недавнего времени являлся основным для Linux-консоли (8-битный режим, именуемый иначе trivial, ныне им лишь эмулируется). В этом случае ввод и вывод осуществляются в традиционных 8-битных кодировках. Причем кодировка ввода транслируется во внутреннее 16-битное представление посредством специальных таблиц соответствия, именуемых в kbd таблицами unimap (unicode console map, живут в каталоге /usr/share/kbd/unicode) или, в console-tools, acm (application character map). Выводимые же символы испытывают обратную трансформацию в 8-битное представление с помощью таблицы sfm (screen font map, штатное место для этих таблиц - /usr/share/kbd/consoletrans).

Так вот, именно эта таблица, sfm, и встраивается в шрифтовой файл, которому присваивается суфикс *.psfu (это - правило номенклатуры, имеющее, как обычно, и исключения, о чем скажу чуть ниже). Делается это потому, что, в отличие от кодовых таблиц, порядок символов в шрифтовом файле никем и ничем не регламентируется, и, в общем случае, может быть любым. А значит, для однозначного вывода в заказанной 8-битной кодировке очень желательно, чтобы нужная таблица соответствия была составной частью шрифтового файла.

Тут я хотел бы еще раз поблагодарить вышеупомянутого Kot'а - раньше я как-то не отдавал себе отчета в том, что набор символов в шифтовом файле - штука абслютно произвольная. Именно это позволяет изготавливать шрифты не только для различных кодировок кириллицы, но и ращличающиеся наборами вспомогательных символов, начиная с буквы "ё" (как известно, в кодировках DOS и KOI8 ее от природы не было) и кончая специфичными для украинского языка знаками (типа "г с чубом"). А в 16-битном режиме в один шрифтовой файл умудряются втиснуть символы для нескольких национальных алфавитов (например, упомянутое ниже семейство LatArCyrHeb). Правда, использовать все теоретическое богатство 16-битных кодировок не удается даже в чистом Unicode-режиме, так как размер консольного шрифта ограничен 512 символами (это связано с каким-то аппаратными ограничениями - точнее сказать не могу). И потому встречающееся обозначение консольных шрифтов как "юникодовских" (грешен, сам им пользовался до недавнего времени) - не более чем жаргонизм: речь идет о шрифтах с несколькими наборами алфавитных символов и встроенной таблицей sfm.

Как легко догадаться, далеко не все шрифты из штатного комплекта любого дистрибутива содержат символы кириллицы. Однако и таких обычно обнаружится десятка три. Если нет - их можно позаимствовать (прямым копирование в должный каталог) из какого-либо Linux-дистрибутива отчественного производства (типа Altlinux или ASPLinux). Или - из пакета console-tools-cyrillic, собранного и периодически обновляемого Виктором Вагнером.

Полная коллекция кириллических экранных шрифтов включает наборы для всех традиционных кодировок Великого и Могучего, получивших распространение на родных просторах - DOS, Windows, KOI8, ISO8859-5, которые опознаются по именам шрифтовых файлов. Шрифты в DOS-кодировке имеют имена типа alt*, Cyr*, cp866* или просто 866* (имена одних и тех же шрифтов в разных дистрибутивах могут варьировать; хотя в принципе шрифты с префиксами alt и Cyr несколько различаются по наборам символов). Шрифты KOI8 (как R, так и U) именуются прозрачно - koi8r и koi8u, соответственно. Шрифты для Win-кодировки имеют в своем имени слово win или цифры 1251. ISO'шные шрифты опознаются по символам iso5 или слову sun (поскольку именно на Sparc'ах главным образом и используются).

По причинам, которые будут рассмотрены в заметке о русификации, практическое значение для экранного вывода в наших условиях имеют почти исключительно шрифты для кодировки DOS. Вне зависимости от того, как их называют, в любом дистрибутиве Linux (за исключением уж совсем американских) можно обнаружить минимум три таких "гарнитуры" (если этот термин в данном случае уместен), именуемые как-нибудь вроде cp866*, cp866-b* и cp866-c*. Они несколько отличаются своим обликом и расположением некоторых редко используемых специальных символов. Впрочем, все три внешне выглядят вполне скверно (особенно при плотности символов, отличной от стандартной).

В отечественных дистрибутивах (и в пакете console-tools-cyrillic) можно найти еще несколько кириллических шрифтов для DOS-кодировки. Например, alt-antiq, стилизованный под старину, или t866, имеющий как бы рукописный облик. Однако и они не вполне подходят для постоянного использования (хотя могут придать вашей консоли вполне оригинальный вид).

И потому очень рекомендую обратить внимание на семейство шрифтов UniCyr*.psf(.gz). Вопреки приведенному выше правилу, эти шрифты содержат в себе таблицу sfm - то самое исключение, поминаемое выше. Среди них можно обнаружить как курьерообразные разновидности, так и вполне честные шрифты Sans Serife (а на мой взгляд, именно шрифты без засечек наиболее подходят для экранного вывода в консоли). Таковых - два, UniCyr-lenta-8x16 и UniCyr-sans-8x16. Их дополнительное достоинство - слабая подверженность деформации при нестандартной плотности символов (напомню, что в консоли мы всегда имеем дело с растровыми шрифтами, и потому их искажение при масштабировании неизбежно). Впрочем, на вкус и цвет товарищей нет, и потому подходящий шрифт каждый может выбрать для себя методом ползучего эпмиризма.

Как уже упоминалось, с некоторого времени в дистрибутивах Linux, претендующих на интернациональность, можно видеть шрифты вида *.psfu.gz или *.psfu. Например, семейство гарнитур, именуемое LatArCyrHeb-* (с высотами матрицы 8, 14, 16 и 19 пикселей). Как легко понять из названия, любой из них пригоден для вывода на экран символов латиницы, кириллицы, арабского и еврейского алфавитов, нужно только указать, какого точно (как - скажу чуть ниже).

Для смены экранного шрифта в текущем сеансе работы служит команда setfont из пакета kbd (в пакете console-tools ей соовтетствует команда consolechars). Дается она с указанием имени шрифта в качестве аргумента, например:

$ setfont UniCyr-sans

что приводит к мгновенной смене экранного шрифта на всех виртуальных консолях. Если шрифты расположены в стандартном для данного дистрибутива каталоге (например, /usr/share/kbd/consolefonts), не требуется ни указания полного пути к имени шрифтового файла, ни его суффикса (вида *.psf.gz). Необходимость и в том, и в другом возникнет, если шрифты берутся из необычного места (например, домашнего каталога пользователя).

В команде consolechars загружаемый шрифт определяется значением опции -f, каковое подчиняется тем же правилам, что и аргумент команды setfont.

Указанной команды достаточно, если мы работаем в режиме trivial, и притом только с одной и той же кодировкой ввода и вывода. На практике же в наших условиях такого почти не бывает - для вывода используется кодировка DOS, для ввода - обычно KOI8-R (или CP1251). И потому необходимо обеспечить загрузку так называемой карты соответствия (mapscreen, то есть таблицы перекодирования набора символов клавиатурного ввода в таковой экранного вывода). Что достигается указанием опции -m, значением которой и выступает имя файла таблицы (они произрастают в том же каталоге /usr/share/kbd/consoletrans, что и sfm-таблицы, хотя вещи это разные). Подробнее об этом будет говориться в заметке о русификации, пока же - лишь несколько соображений рецептурного характера.

Первое - если после исполнения команды setfont имя_шрифта вместо русского текста на экране наблюдаются всякого рода безобразия, команду следует повторит в виде

$ setfont UniCyr-sans -m koi2alt

где значение опции -m указывает на имя mapscreen. В особо тяжелых случаях (при нерусифицированной системе, или при открытии новой виртуальной консоли в соответствии с ранее описанными методами), возможно, придется этот самый mapscreen еще и активизировать вручную вводом т.н. "магической последовательности"

$ echo -ne '(K'

Без этого русские буквы будут видны только на той консоли, с которой была дана команда setfont (она автоматически активизирует нужную кодировку, но только - на текущей консоли).

Если принято решение использовать для вывода шрифты в кодировке KOI8, отпадает требование не только вывода "магической последовательности", но и опции -m в команде setfont. Оно и понятно - ведь при этом в случае 8-битного режима и для ввода, и для вывода используется один и тот же набор символов.

В 16-битном режиме необходимо выполнить две трансляции символов - сначала из кодировки ввода в Unicode-представление, а затем - в кодировку вывода. Первая осуществляется той же опцией -m, которая теперь приобретает значение имени unimap-файла, вторая же - опцией -u, в качестве значения которой задается имя sfm-таблицы:

$ setfont cp866-8x16 -m koi8-r_to_uni -u cp866

Если загружаемый шрифт уже содержит встроенную sfm-таблицу, опцию -u задавть не нужно (точнее - нельзя), опция же -m потребуется в любом случае, например:

$ setfont LatArCyrHeb-16 -m koi8-r_to_uni

Подчеркну, что в этом случае, в отличие от 8-разрядного режима, опция -m обеспечивает перекодирование символов ввода не прямо в их экранное воплощение (то есть кодировку шрифта), а во внутреннюю кодировку Unicode.

Режим с 16-битным внутренним представлением теоретически является более гибким и более прогрессивным (особенно - в Unicode-варианте). Однако 8-битный режим отнюдь не потерял своего значения - и не только обратной совместимости ради. Дело в том, что, как будет показано в соответствующей заметке, русификация консоли в нем осуществляется простым, отработанным и абсолютно предсказуемым комплексом мер, применимых к любому произвольному дистрибутиву Linux. Тогда как русификация 16-битного режима более дистрибутиво-зависима и не всегда предсказуема. По крайней мере, до недавнего времени было именно так. Нынче, с активным вредрением UTF-8 (и ее поддержкой терминальными библиотеками и консольными приложениями), ситуация, видимо, упростится.

Рано или поздно упражнения со шрифтами заканчиваются достижением идеального (или, по меньшей мере, оптимального) варианта. Который хотелось бы увековечить как загружаемый по умолчанию при старте системы. Сделать это не очень-то и трудно, сложнее дать однозначные рекомендации, как именно. Поскольку метод загрузки "умолчального" шрифта очень зависит от системы инициализации, принятой в конкретном дистрибутиве.

В клонах Red Hat, наколько я помню, это достигается изменением значения строки SYSFONT в конфигурационном файле /etc/sysconfig/i18n. В других дистрибутивах "умолчальный" шрифт может изменяться в других конфигах из каталога /etc и его подкаталогов - сверяйтесь с документацией. А в почти любых неясных случаях самое место для подгрузки шрифта - файл /etc/rc.local, куда можно поместить строку вида

setfont UniCyr-sans -m koi2alt

Не забыв сопроводить ее сценарием инициализации mapscreen на всех открываемых при старте виртуальных консолях, о чем подробно будет сказано в заметке по русификации.

Теоретически рассуждая, шрифт, загружаемый по умолчанию, можно вкомпилировать в ядро системы (во FreeBSD такая возможность предусмотрена в штатной документации). Преимущество этого метода - доступ к кириллическим шрифтам при всякого рода аварийных загрузках (например, при подмене штатного процесса init командной оболочкой путем передачи ядру параметра init=/bin/shell_name). Это позволит для исполнения ремонтно-спасательных действий прибегнуть к подсказкам из русскоязычной документации. Однако сам я такую процедуру не проделывал. Могу только предполагать, что она потребует изменения исходников файлов типа /usr/src/linux/drivers/char/console*. За любые соображения по сему предмету буду благодарен.

Шрифтовой терминатор

В дополнение к заметке об украшении консоли я хочу рассказать о замечательном пакете terminus-fonts, о котором узнал недавно благодаря Kot'у, за что ему большое спасибо. Пакет этот болгарского происхождения и проживает здесь - в виде архива tar.gz объемом около 100 Кбайт. Его можно найти также в портах FreeBSD и в портежах Gentoo, вероятно, и в других местах. Для FreeBSD, в частности, он доступен и в качестве бинарного пакета.

Terminus-fonts - не просто шрифтовой набор, а универсальный инструмент для генерации терминальных шрифтов любого назначения. Он включает в себя

  • шрифтовые файлы базовой гарнитуры в формате BDF (Bitmap Distribution Format) нормального и полужирного начертания, высотой от 14 до 24 пикселей, в кодировке Unicode;
  • набор скриптов для преобразования их в шрифтовые файлы различных используемых Unix-консолями и X-терминалами форматов;
  • make-файлы для соответствующих преобразований;
  • необходимые дополнительные данные, в частности, unimap-таблицы для преобразования 8-битных кодировок в Unicode;
  • файлы документации на английском и болгарском языках.

В README-файлах дается исчерпывающее описание того, как обращаться с пакетов. И потому я лишь кратко опишу доступные возможности. Итак, базовые bdf-шрифты могут быть преобразованы в шрифтовые файлы следующих форматов:

  • raw-формат, в котором шрифтовой файл содержит только бинарные данные; этот формат используется для вывода в консольных драйверах BSD-семейства (syscons FreeBSD, pcvt и wscons);
  • psf-формат, включающий, кроме собственно шрифтовых данных, заголовок и psf-сигнатуру с дополнительной информацией о шрифте; это - основной формат вывода в Linux-консоли;
  • pcf-формат для вывода на X-терминалах.

Генерация шрифтовых файлов осуществляется командой make с указанием соответствующей цели, например,

make raw

для создания raw-файлов,

make psf

и

make pcf

для psf- и pcf-форматов, соответственно. Кроме того, командой

make txt

можно сгенерировать smf-таблицы для ряда кодировок. В чем, впрочем, необходимости как будто нет, так как эти таблицы встраиваются, судя по README, в собственно psf-файл.

Каждое шрифтоначертание автоматически генерируется в нескольких кодировках: ISO8859-1/2/5/9/15/16, Windows-1250/1251/1252/1254, IBM-437/852/855/866, KOI8-R/U/E/F, Bulgarian-MIK, Paratype-PT154/PT254 и Macintosh-Ukrainian. Поскольку все шрифты - более чем 500-символьные, для Linux-консоли можно подобрать любые сочетания кодировок ввода и вывода. Правда, для BSD-консоли шрифты с традиционной для нее кодировкой вывода CP866 сами собой не образуются (впрочем, об использовании terminus-fonts в этой ОС - см. соответствующую заметку).

Качество консольных шрифтов исключительно высокое. При этом их внешний вид и читабельность не ухудшаются при нестандартной плотности знаков. Правда, их вариации для X-терминалов именно в терминале выглядят достаточно непривычно. Однако там - и своих, Иксовых, шрифтов нынче вдоволь. А для чисто текстового режима - пожалуй, ничего лучше не придумаешь. Короче говоря, очень рекомендую...

Консоль в цвете

На мой взгляд, подбора подходящего шрифта довольно для придания консоли презентабельного вида. Однако при желании можно заняться и ее расцвечиванием (хотя, повторяю, монохромный стиль консоли столь же естественен, как и черно-белая гамма козинцевского "Короля Лира").

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

Для изменения цветовой гаммы используется неоднократно поминавшаяся ранее команда setterm (из пакета ulil-linux), для чего в ней имеются опции -foreground [цвет] и -background [цвет], изменяющие цвет текста и фона, соответственно. Значения обеих задаваются в 8-цветной палитре - black, blue, green, cyan, red, magenta, yellow. Кроме того, с помощью опции -reverce можно "поменять местами" цвет текста и фона, сделать текст мигающим (посредством опции -blink), выделенным (с опцией -bold) или, наоборот, "приглушенным" (с опцией -half-bright). Все опции, определенные для команды setterm (подробности см. в man (1) setterm), имеют силу только для текущей виртуальной консоли (почему цвет и используется для их различения; хотя, на мой взгляд, это проще и эффективнее сделать средствами командной оболочки zsh).

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

Во-вторых, развитые командные оболочки имеют собственные средства манипуляции цветами, которые (для /bin/bash, например) задействуются по умолчанию во многих дистрибутивах. А сочетание изменений цветов через setterm и командную оболочку может привести к совершенно непредсказуемым эффектам, вплоть до полной нечитаемости текста.

И в третьих, многие программы (например, всенародно любимый Midnight Commander) сами по себе изменяют свойства терминала, сбивая настройки setterm после выхода из них. Чтобы этого не происходило, команду setterm следует давать с дополнительной опцией -store, сохраняющей в качестве умолчаний уставновленный ею набор терминальных атрибутов.

Тем не менее, если результаты цветовых экспериментов показались удачными, измененные цвета фона и текста можно сделать постоянными. Для этого достаточно включить команду setterm с требуемыми значениями опций в один из стартовых файлов (например, в тот же /etc/sysconfig/i18n в Red Hat клонах или в /etc/rc.local - во многих дистрибутивах, использующих BSD-стиль инициализации).

И последнее, что я хотел бы сказать о цветах. Консольный драйвер FreeBSD (syscons) позволяет менять цвет не только текста и фона, но и бордюра экрана отдельно для каждой виртуальной консоли. Что такое бордюр, помнят, пожалуй, только пользователи старых четырнадцатидюймовиков без средств цифрового управления: это та самая черно-серая кайма между изображением и пластмассой окаемки дисплея. В старых DOS-русификаторах, помнится, изменение ее цвета использовалось для индикации текущей раскладки клавиатуры (латиницы или кириллицы). Однако на любом современном мониторе бордюр обычно сводят под ноль. Тем не менее, и его можно использовать в мирных целях (например, придав бордюру root-консоли тревожный красный цвет).

В Linux'е штатного средства для этого не имеется. Однако на сайте винницкой фирмы Крон я обнаружил патч к ядру, как будто бы позволяющий менять цвет бордюра аналогично тому, как это делается во FreeBSD. К сожалению, патч этот предназначен для достаточно старой версии ядра, и в современных ядрах работосопособность его гарантировать нельзя (у меня - не прошел ни с одной версией линии 2.4.X, так что с 2.6.X - даже и не пытался).