Концепция Base Linux и ее воплощение
К понятию Base Linux я пришел, размышляя над вопросом: а что же такое ОС Linux? Результаты своих размышлений я неоднократно излагал в Сети и на бумаге, начиная с давнишней заметки в онлайновой Софтерре (Из чего только сделаны Linux'ы2002 год) и заканчивая соответствующей главой в книге "Свободный Unix: Linux, FreeBSD и другие", которая готовится к печати издательством БХВ-Петербург (ее прототип известен в Сети как "Введение в POSIX'ивизм и доступен на сайтах Линуксцентр и Цитфорум). За прошедшие годы мои представления о предмете неоднократно корректировались (в частности, под влиянием статьи Тихона Тарнавского - /open_source/open_source/baselinux_tt). И потому в настоящем сочинении я решил систематизировать все, относящееся к Base Linux, и изложить свое сегодняшнее видение этого вопроса.
Прежде чем переходить к рассмотрению Base Linux, нужно ответить на вопрос - что же такое операционная система? По сему поводу существует три точки зрения - минималистская, максималистская и, так сказать, промежуточная:
- с минималистской точки зрения, операционная система - это программа, именуемая ядром ОС;
- согласно максималистской точке зрения, операционная система - это не столько ядро, сколько надстраивающая его инфраструктура, включающая самодостаточный комплекс системных утилит и пользовательских приложений, а также средства управления оными;
- промежуточная точка зрения сводится к тому, что операционная система образована ядром и комплексом средств, обеспечивающих его функциональность.
Я не буду здесь вдаваться в обсуждение того, какая из трех точек зрения правильна. Тем более, что понятие операционной системы может меняться в зависимости от того, о какой именно ОС идет речь. Так, Windows любого рода, из которой, практически, невозможно вычленить собственно ядро без вреда для ее здоровья, - безусловно, скорее именно инфраструктурный комплекс, то есть подпадает под второе определение операционной системы. FreeBSD (и другие представители BSD-семейства) являет собой неразрывное единство ядра и средств его поддержки - системных утилит и некоторых пользовательских приложений, выступающих в этом контексте также в качестве системных. То есть соответствует третьему определению. Ну а Linux традиционно рассматривается как "голое" ядро, надстраиваемое независимыми (от ядра) системными и пользовательскими программами сторонних разработчиков. Однако ниже я постараюсь показать, что такая точка зрения не совсем верна, и, как будет сказано в последних строках, Linux представляет собой четвертый вариант определения операционной системы.
Что такое ядро? Это - (почти) обычная программа, на которую возложены не совсем обычные функции: если прочие программы выполняют какие-либо системные или пользовательские задачи, то ядро только что и обеспечивает их взаимодействие между собой и с аппаратурой компьютера. В академических трудах по Unix (например: С. Д. Кузнецов, Операционная система UNIX) функции ядра обычно группируются в несколько подсистем управления - процессами, памятью, устройствами, сетевую подсистему и подсистему ввода/вывода. С точки зрения пользователя, функциональность ядра определяется его способностью работать с наличным "железом" - звуковой и видеокартой, обращаться к винчестеру конкретного типа, понимать несомую им файловую систему, и так далее. Функции эти могут быть как жестко встроены в ядро, так и подключаться к нему в качестве загружаемых модулей.
В этом плане ядро Linux само по себе многое знает и много чего умеет:
- поддерживает практически весь спектр базового оборудования (процессоров, чипсетов, шин и дисковых контроллеров);
- все более растущий круг дополнительных устройств - по мере их появления и распространения;
- все сетевые протоколы и подавляющее большинство сетевых интерфейсов;
- способно использовать в качестве "родных" (native) множество файловых систем: от "самой родной" ext2fs/ext3fs, включая специально разработанную для Linux ReiserFS/Reiser4, вплоть до первоначально "чуждых" XFS и JFS, и даже FAT любого рода;
- и многое, многое другое.
Но достаточно ли этого, чтобы обратить эти знания и умения на пользу обществу (точнее, сообществу Linux-пользователей)?
Для того, чтобы ядро Linux приступило к выполнению своих прямых обязанностей, его необходимо предварительно загрузить (впрочем, это касается и любой другой операционки). Может ли оно сделать это само по себе?
В принципе, да, может. Образ ядра содержит в себе загрузочную запись, способную принять управление непосредственно от BIOS компьютера или из главной загрузочной записи (MBR - Master Boot Record) винчестера. Такой процесс самозагрузки ядра называют иногда bootstrapping - поднятие себя за шнурки от собственных ботинок.
Однако на практике это оказывается почти столь же неудобным, как и процедура подъема вышеуказанным способом. Потому что образ ядра, предназначенный для непосредственной загрузки, должен быть размещен на специальном дисковом разделе, причем - без файловой системы: ведь для того, чтобы распознать образ ядра как файл, а не последовательность нулей и единиц, нужно иметь загруженное ядро с поддержкой данной файловой системы, а ядро-то у нас еще не загружено. Выделять же специальный первичный раздел только под образ ядра представляется слишком жирным - ведь на диске в PC-архитектуре таких разделов может быть всего четыре. Кроме того, такой способ лишает возможности использовать Linux в паре с какой-либо другой ОС.
Так что на практике прямая загрузка образа ядра используется, насколько мне известно, только при изготовлении загрузочных дискет, и с отмиранием флоппи-приводов забудется окончательно. А штатным средством загрузки ядра Linux (и, следовательно, необходимым компонентом его функционирования) оказывается одна из программ, так и называемых - загрузчиками, обычно с эпитетами - начальный, системный или мультисистемный.
В процессе загрузки ядра происходит множество сложных процессов, включая опознание оборудования и загрузку модулей - ведь мы только что говорили, что те или иные функции неизбежно реализованы в виде модулей, а без их загрузки они как бы и не существуют. Кроме того, загрузка и выгрузка модулей могут потребоваться и в дальнейшем. Но может ли ядро само по себе загружать модули при старте или в процессе работы? Нет, средств для этого в нем не предусмотрено. Из чего вытекает необходимость в инструментах управления модулями - загрузки, выгрузки, построения зависимостей, средств просмотра состояния. И наличие их - второй непременный компонент успешного функционирования ядра.
Завершение загрузки ядра знаменуется стартом процесса инициализации. В ходе ее происходит монтирование файловых систем, включение разделов своппинга, активизация виртуальных терминалов и тому подобные действия, завершающиеся приглашением пользователя к авторизации. И все эти действия также выполняются не средствами ядра, а специальными инструментами. Следовательно, их набор (он так и называется - сценарии инициализации, или стартовые скрипты) необходим нам еще на стадии входя в систему, и являет собой третий непременный компонент, обеспечивающий функциональность ядра.
Но вот образ ядра загружен и инициализация системы выполнена. И ядро готово к выполнению своих функций - работать с файловыми системами, сетевыми устройствами и прочими атрибутами, сопровождающими современную персоналку. Однако как? Ведь для этого нужны средства реализации функций ядра. Какие? Проще пояснить на примере.
Выше было сказано, что ядро Linux поддерживает массу файловых систем. Однако это означает лишь принципиальную возможность работы с ними. Но ни одна из поддерживаемых ядром файловых систем не возникает сама собой - ее нужно создать, подключить к системе (как говорится, смонтировать), в дальнейшем, возможно, осуществлять проверку ее состояния, и так далее. И все это требует комплекса соответствующих программ - своего для каждой из поддерживаемых файловых систем, - иначе пользователю будет мало радости от их изобилия.
Аналогично и с сетевыми протоколами и устройствами, виртуальными терминалами,и так далее: кроме поддержки ядром, все это требует еще и внешнего инструментария для управления ими, иначе соответствующая функция оказывается "мертвой". И весь этот инструментарий можно объединить в комплекс средств обеспечения базовой функциональности ядра - четвертый обязательный компонент системы.
Однако каким образом пользователь получит доступ ко всем этим базовым функциям? Для этого ему требуются соответствующие средства. Например, для доступа к "рабочей" (то есть известной и смонтированной) файловой системе нужны средства просмотра ее содержимого, средства управления файлами (копирования, перемещения, переименования, удаления), средства просмотра содержимого отдельных файлов и, при необходимости, их модификации (то есть средства управления контентом файлов). Причем кое-какие из этих средств оказываются необходимыми уже на стадии инициализации, поскольку используются в тех самых сценариях ее (стартовых скриптах), где они запускаются автоматически.
Пользователю же требуемые утилиты доступа к файловой системе (и средства доступа к другим функциям) приходится запускать вручную. Для чего ему требуется какой-то интерфейс, позволяющий это делать. Поскольку необходимые пользовательские утилиты запускаются соответствующими командами, в качестве такого интерфейса в Unix-подобных системах традиционно используется программа, называемая командной оболочкой, командным интерпретатором или, по простому, шеллом (shell - оболочка). Она выступает в качестве интегратора вышеуказанных пользовательских утилит, среды для их выполнения и, вместе с ними, может быть объединена в комплекс, так сказать, боевого обеспечения пользователя - пятый компонент, необходимый для функционирования ядра на его, пользователя, благо.
Вот, казалось бы, и все. Но нет, в тени, за кадром, осталась еще одна вещь, без которой все перечисленное выше просто не будет работать. Это, невидимое пользователю, средство, так сказать, его тылового обеспечения, - общесистемная библиотека функций Си (libc).
Таким образом, для загрузки ядра, его работы и использования, необходимы следующие компоненты:
- само ядро (ну еще бы);
- стартовые утилиты - средства загрузки образа ядра, управлениями подключаемыми модулями и инициализации системы;
- утилиты поддержки - средства обеспечения базовой функциональности ядра;
- средства боевого обеспечения - шелл и пользовательские утилиты;
- средства тылового обеспечения - системные библиотеки, в первую очередь библиотека функций Си.
Этот комплекс средств составляет основу системы Linux, его можно обнаружить в составе абсолютно любого варианта этой системы. С одной стороны, любой из его компонентов абсолютно необходим для функционирования системы, с другой - он обеспечивает ее самодостаточность. И потому резонно назвать его Base Linux и считать воплощением этой ОС как системной целостности.
Очевидно, что ядро Linux - основной (и, можно сказать, эпонимический) компонент этой ОС. Созданное Линусом Торвальдсом в 1991 году, оно на протяжении уже многих лет разрабатывается большим интернациональным коллективом под руководством и при координации основоположника. Команда разработчиков - более или менее неформальное объединение. И теоретически каждый желающий (и, главное, могущий) имеет шанс принять участие в разработке ядра путем посылки своих дополнений (patch). Хотя практически все эти патчи проходят многоступенчатый отбор, прежде чем попасть (или не попасть) к самому Линусу, который и принимает окончательное решение - включать их в официальную версию ядра, или нет.
Официальным своим местопребыванием ядро имеет сайт http://www.kernel.org, имеющий множество зеркал по всему свету, в том числе и в России. В сущности, исходные тексты ряда версий ядра, их патчей от независимых разработчиков, вместе с некоторыми сопутствующими программами, и составляют единственное содержание этого сайта. С которого их можно получить по Сети - по протоколам HTTP или FTP. Иного способа распространения исходников ядра, насколько мне известно, не существует.
Бытует мнение, что ядро Linux - одно-единственное. Это правда, но не вся правда. Действительно, ядро Линуса - каноническое. Однако практически, кроме текущей его ветки (в настоящее время - 2.6), в которой периодически выходят новые версии (2.6.X) в каждый момент времени развивается и дополняется минимум одна предшествующая ветка (на данный момент 2.4). А одна из еще более старых веток (ныне - 2.2) поддерживается на уровне исправления ошибок. Ошибки, разуеется, имеют место быть и в текущей ветке, где они активно выявляются и исправляются, что образует отдельную "корректирующую" ветку (2.6.X.Y).
Далее, существуют т.н. ядра майнтайнеров (наиболее известные из них - Эндрю Мортон, Алан Кокс, Кон Колинас). Разумеется, в основе всех их - каноническое ядро, но - с патчами, ответственными за реализацию дополнительных функций, не входящих в официальное ядро. Собственно, ядра майнтайнеров и распространяются исключительно в виде патчей к основному дереву исходников ядра. В большинстве случае они доступны на том же http://www.kernel.org, в каталоге people , где каждый майнтайнер имеет свой подкаталог. Со временем большинство патчей майнтайнеров включается в состав официального ядра. Однако эти ребята на достигнутом не останавливаются, и придумывают новые патчи для обеспечения новых возможностей. Так что основные майнтайнерские ветки перманентно существуют параллельно канонической ветке Линуса.
Существуют проекты дополнения ядра узкоспециальными функциями, такими, как обеспечение работы кластеров (OpenMosix) или повышенной безопасности (SELinux). Разрабатываемые в их рамках патчи обычно не включаются в основное дерево, и они сосуществуют с ним в качестве отдельных веток.
Кроме этого, существуют еще и ядра дистрибьюторов - в комплект всех распространенных дистрибутивов, таких, как Red Hat, Suse, Mandrake и так далее, входят заточенные под них ядра собственной выделки (обычно в нескольких вариантах), дополняющие или подменяющие каноническое ядро. Они основаны на патчах майнтайнеров или специализированных проектов, но включают и собственные функции, обеспечивающие оптимальную работу "своего" дистрибутива. Более того. существуют глубокие сомнения в том, что, скажем, Red Hat вообще способен функционировать на каноническом ядре - или каком-либо ином, отличном от собственных.
Таким образом, альтернативность Base Linux начинается с самой наибазовой его части - ядра. Можно воспользоваться каноническим ядром, в том числе и с корректирующими патчами, можно дополнить его необходимыми функциями из патчей майнтайнеров или специализированных проектов, а можно и прибегнуть к результатам тех, кто такую работу уже проделал, подобрав подходящее ядро от дистрибьюторов.
Если не говорить о самозагрузке (а мы вроде договорились не поднимать себя за шнурки от собственных ботинок), то ядро Linux можно загрузить множеством внешних программ-загрузчиков: BSD loader (штатный загрузчик BSD-систем), загрузчиком Windows NT/2000/XP, коммерческими программами типа Acronis OS Selector, вероятно, и другими. Существует даже средство загрузить ядро Linux с помощью программы, запущенной из DOS (loadlin). Однако наиболее часто с этой целью применяется два пакета: Lilo и GRUB.
Lilo (LInux LOader), как явствует из его названия, специально разрабатывался именно для обеспечения загрузки ядра Linux, хотя способен выступить и в качестве мультисистемного загрузчика, успешно справляясь с запуском Windows любого рода, а также FreeBSD. Пакет lilo не имеет авторского сайта, но доступен на многих серверах, например: ftp://ftp.metalab.unc.edu/pub/Linux/system/boot/lilo.
В отличие от Lilo, GRUB разрабатывался именно как мультисистемный загрузчик, и имеет все шансы стать стандартным для свободных ОС. В отличие от большинства мультисистемных загрузчиков, он не просто передает управление "по цепочке" на загрузочный сектор соответствующего раздела, но работает с несмонтированными файловыми системами (незагруженных ОС!), обеспечивая запуск с них ядра соответствующей системы. И, добавлю, выступая как своего рода мини-ОС. Получить его можно с сайта проекта - http://www.gnu.org/software/grub/.
Я уже говорил, что как в ходе загрузки ядра, так и позднее, возникает необходимость в инструментах управления модулями - загрузки, выгрузки, построения зависимостей, средств просмотра состояния. Они составляют содержание пакета module-init-tools (или, для версии 2.4.X - modutils ). Пакеты для управления модулями привязаны не только к ветке ядра, но и к его конкретной версии, и потому они оказываются неразрывно связанными с ядром. Что подчеркивается их нахождением на том же сайте http://www.kernel.org.
Пакет module-init-tools включает в себя следующие команды:
lsmod - просмотр загруженных модулей;
depmod - генерация зависимостей между модулями;
genksyms - генератор файла информации о версии ядра, к которой относятся модули;
insmod - команда для загрузки единичного модуля;
insmod_ksymoops_clean - команда для удаления модулей, не используемых в течении некоторого времени;
kernelversion - команда для вывода номера ветки ядра - в текущем случае это будет 2.6;
modinfo - команда для вывода информации о модуле, заданном в качестве ее аргумента;
modprobe - загрузка модуля, заданного в качестве ее аргумента, и всех модулей, связанных с ним зависимостями;
rmmod - удаление ранее загруженного модуля.
В пакет modutils входят, с некоторыми отклонениями, те же команды аналогичного назначения.
Основное средство инициализации - канонический пакет sysvinit (ftp://ftp.cistron.nl/pub/people/miquels/sysvinit/), обеспечивающий инициализацию системы в т.н. стиле System V, принятой в Linux в качестве стандартной. Он включает программу init , обеспечивающую запуск всех остальных процессов в системе, shutdown , halt , reboot , вызывающие останов и рестарт системы, killall - средство "убиения" процессов, и еще несколько.
Пакет sysvinit вызывает в последнее время все больше нареканий. И потому предпринимаются поиски его альтернатив, примерами которых являются Simpleinit-MSB (http://www.winterdrache.de/linux/newboot/index.html), runit (http://smarden.sunsite.dk/runit/) и InitNG (http://jw.dyndns.org/initng/).
Кроме того, для старта полнофункциональной системы требуются и некоторый набор стартовых скриптов, обеспечивающих запуск основных системных сервисов. Однако они настолько зависимы от конкретного дистрибутива, что перечислить их здесь просто невозможно. Тем более, что их можно написать (или, по крайней мере, скорректировать) и собственноручно. Замечу только, что все наборы стартовых скриптов можно разделить на две группы - в стиле System V и в BSD-стиле. Различие между ними в том, что наборы BSD-стиля обеспечивают запуск системных сервисов посредством главного стартовго сценария, получающего параметры из главного же стартового конфига (примером может служить пакет bsd-init из дистрибутива Archlinux, http://www.archlinux.org). В наборах стиля System V ни того, ни другого не имеется, системные службы запускаются отдельными скриптами, сгруппированными по так называемым уровням запуска. Хорошее представление о составе такого набора можно получить, ознакомившись с пакетом lfs-bootscripts проекта Linux from Scratch (http://downloads.linuxfromscratch.org/).
Таким образом, средства загрузки ядра Linux и инициализации системы весьма разнообразны, предоставляя возможность выбора и тех, и других.
Важнейшие утилиты поддержки Linux объединены в пакет, который так и называется - util-linux . Очень желательно, чтобы его версия соответствовала версии ядра. За чем можно проследить, соответственно, на том же http://www.kernel.org - каталоге ftp://ftp.kernel.org/pub/linux/utils/util-linux/.
В составе пакета util-linux - многие множества команд весьма разного назначения, даже перечислять которые было бы слишком долго (а также скучно и не нужно). Они предназначены для создания дисковых разделов (fdisk , cfdisk ), создания (mkswap ) и активации/дезактивации (swapon /swapoff ) разделов подкачки, монтирования и размонтирования файловых систем (mount /umount ), установки атрибутов терминала (setterm ), и многого, многого другого.
К util-linux , включающей, помимо прочего, команду активации терминала (agetty ), по смыслу примыкает пакет shadow (ftp://ftp.pld.org.pl/software/shadow/), предназначенный для управления пользовательскими паролями, который обеспечивает, в частности, механизм так называемых "теневых" паролей, общепринятый в Linux.
Существуют и многочисленные альтернативные средства авторизации в системе. Так, универсальная команда agetty , обеспечивающая доступ, в том числе, и к удаленным терминалам, в условиях настольной персоналки может заменяться командой mingetty , приспособленной для работы только с виртуальными терминалами. Интересен метод беспарольного входа в систему, который можно обеспечить с помощью пакета qlogin ().
С давних уже пор ядро Linux поддерживает так называемые мультидисковые устройства - программные RAID-массивы и механизм LVM (Logival Volume Management), обеспечивающий, в частности, "горячее" перераспределение дискового пространства между файловыми системами. Разумеется, обеспечение этих функций требует соответствующего инструментария - для их создания и последующего управления. Работа с RAID-массивами обеспечивается сразу двумя альтернативными пакетами: mdadm (http://www.cse.unsw.edu.au/~neilb/source/mdadm/), более подходящим для пользовательских десктопов, и raidtools (), чаще применяемом на серверах. А механизм LVM обеспечивается одноименным пакетом (ftp://ftp.sistina.com/pub/LVM/).
Средства поддержки файловой системы (систем) включают в себя утилиты для создания их (сиречь форматирования, в терминах DOS/Windows), проверки на целостность, тюнинга, резервного копирования и т.д. Для классической файловой системы Linux, ext2fs, такой набор носит название ext2fsprogs , а найти его можно, например, здесь: ftp://ftp.metalab.unc.edu/pub/Linux/system/filesystems/ext2/. В него входят следующие утилиты:
badblocks для поиска испорченных блоков на дисковых устройствах; chattr для смены атрибутов файлов;
dumpe2fs для создания точных дисковых копий - дампов;
ext2fs , mke2fs и mkfs.ext2 для создания на дисковых разделах файловой системы;
e2fsck , fsck и fsck.ext2 , осуществляющие проверку целостности файловой системы;
- e2image для создания образа файловой системы в виде файла;
e2label для создания таблицы разбиения диска;
tune2fs для настройки быстродействия файловой системы.
Ряд утилит пакета поддерживают также журналируемый вариант файловой системы Linux - ext3fs (mke2fs , fsck.ext3 ), а resize2fs - также и ReiserFS. Однако в принципе для нее, как и для остальных журналируемых файловых систем - XFS и JFS, требуются собственные средства.
В первом случае это будет пакет reiserfsprogs (ftp://ftp.namesys.com/pub/reiserfsprogs/), включающий
mkreiserfs для создания файловой системы ReiserFS;
reiserfsck для проверки ее целостности;
resize_reiserfs для изменения размера и размонтирования;
Для поддержки XFS требуется целый комплекс пакетов:
acl для дополнительных средств управления доступом к файлам;
attr для использования расширенных возможностей атрибутирования
файлов;
dmapi ;
xfsdump для резервного копирования;
xfsprogs собственно для создания и управления файловой системой XFS.
Все эти средства могут быть получены (в том числе и в виде исходников) с
соответствующего раздела сайта SGI: ftp://oss.sgi.com/projects/xfs/download/latest/cmd_tars/.
Впрочем, абсолютно необходимым из этого списка является только последний пакет, xfsprogs , без всего остального можно обойтись. Что же касается средств поддержки JFS, поиск таковых предлагается проделать самостоятельно заинтересованным лицам (автор к их числу не относится).
Кроме этого, требуются средства для поддержки виртуальной файловой системы proc, обеспечивающей отображение процессов - procinfo (ftp://ftp.cistron.nl/pub/people/svm/), procps (ftp://people.redhat.com/johnsonm/procps/) и, возможно, средство для трансляции файловой системы устройств - devfs, devfsd, буде возникнет желание таковую использовать (ftp://ftp.kernel.org/pub/linux/daemons/devfsd/). Хотя ныне devfs быстро вытесняется другим механизмом управления устройствами - пакетом udev , который, таким образом, вместе с тесно связанным с ним пакетом hotplug , становится необходимым компонентом группы поддержки. Оба они находятся здесь: ftp://ftp.kernel.org/pub/linux/utils/kernel/hotplug
К этой же группе примыкает пакет psmisc, предназначенный для отслеживания процессов в системе. В его составе - команды:
fuser , выводящая на экран идентификаторы процессов,
killall , предназначенная для отправки сигналов им,
pstree , показывающая запущенные процессы в виде дерева.
Информация о протекающих в системе процессах должна как-то фиксироваться (в частности, на предмет анализа причин сбоев). И этой цели служит специальный пакет - sysklogd (http://www.infodrom.org/projects/sysklogd), включающий утилиты klogd (демон сообщений ядра) и syslogd, ведущий запись сообщений системных программ.
Далее, к средствам поддержки можно отнести программы для работы с консольным драйвером Linux. Таковых ныне используется две - kbd ftp://ftp.win.tue.nl/pub/linux-local/utils/kbd/ и console-tools (http://telia.dl.sourceforge.net/sourceforge/lct/). Первая включает в себя множество утилит, из которых для начала важнейшими являются:
loadkeys , предназначенная для загрузки клавиатурных раскладок;
setfont для загрузки экранных шрифтов;
mapscrn для задания карты соответствия кодировки клавиатурного ввода таковой экранного вывода.
Набор console-tools имеет соответствующие средства - loadkeys и consolechars для управления вводом/выводом. Очевидно, что пакеты kbd и console-tools не то чтобы исключают друг друга - просто при наличии одного второй делается ненужным. Пакет console-tools считается более современным, однако и текущие версии kbd обеспечивают, в частности, работу с кодировкой Unicode и прочие актуальные фичи, так что выбор между ними - дело вкуса.
Сетевые возможности базовой системы обеспечиваются двумя наборами - netkit-base (ftp://ftp.uk.linux.org/pub/linux/Networking/netkit/) и net-tools (ftp://ftp.uk.linux.org/pub/linux/Networking/netkit/). В первом - демон inetd, отвечающий за службы Интернет вообще, и команда ping , для отправки пакетов, определяющих доступ к узлам сети. Команды набора net-tools определяют конфигурацию сети (ifconfig ), доменные имена, имена хостов и т.д. А для обеспечения работы по протоколу PPP (Point-to-Point), обеспечивающему, в частности, модемный доступ к сети, существует соответствующий пакет - ppp ().
В это понятие, как я уже говорил, включаются средства обеспечения взаимодействия пользователя с системой. С одной стороны, они обеспечивают минимальную пользовательскую ее функциональность, с другой - играют служебную (но - совершенно незаменимую) роль во многих системных процессах.
На первом месте здесь должно поставить командную оболочку - без нее никакие вообще действия становятся невозможными: ведь, кроме того что она обеспечивает ввод всех пользовательских и системных команд, она необходима и для исполнения стартовых сценариев при загрузке системы.
Традиционно такой, как бы общесистемной, командной оболочкой в Linux является bash (ftp://ftp.gnu.org/gnu/bash/). Хотя обычно стартовыми сценариями в явном виде вызывается некая оболочка /bin/sh , это - не более чем ссылка на bash : при этом под /bin/sh понимается некий виртуальный POSIX-shell, в природе не существующий. Однако любая POSIX-shell оболочка, будучи запущен таким образом, более или менее его эмулирует.
Оболочка bash - далеко не единственно возможная для использования в Linux. Некоторые оболочки превосходят ее компактностью (например, ash (http://ftp.debian.org/debian/pool/main/a/ash/), иные же (в частности, zsh , http://www.zsh.org) - богатством настроек и удобством в интерактивной работе. Правда, все в Linux настолько завязано на bash-скриптинг, что она кажется безальтернативной как общесистемный шелл. И к тому же ее возможности почти неограниченно расширяются с помощью дополнительного пакета bash-completion (http://www.caliban.org/files/bash/), который способен воспроизвести почти все функции zsh . Тем не менее, как можно видеть, альтернативы bash существуют. Так, ash часто используется во всякого рода минидистрибутивах, а zsh в качестве общесистемного шелла я, с целью эксперимента, использовал в Linux-системе собственной сборки.
Далее следует базовый пакет пользовательских утилит для манипуляций с файлами и их содержимым, в первую очередь текстовым - coreutils (http://ftp.gnu.org/gnu/coreutils/). Он включает огромное количество отдельных команд, которые можно разделить на три блока - средств для работы с файлами, средств навигации по файловой системе и средств работы с текстовым контентом. Ранее они составляли три отдельных пакета - fileutils , sh-utils и textutills , соответственно.
Средства манипуляции файлами - следующие:
chgrp , chmod и chown для управления атрибутами файлов;
cp , dd и ln для простого копирования файлов, копирования с преобразованием и создания ссылок, а также install для копирования с
установкой атрибутов;
touch , mkdir , mkfifo и mknod - средства создания регулярных файлов, каталогов, специальных файлов и файлов устройств, соответственно;
mv , rm , rmdir для переименования/перемещения файлов, их удаления, удаления каталогов;
ls , dir и vdir для просмотра списков файлов в каталогах;
dircolors для установки цветовой схемы;
df и du для вывода информации о дисковом пространстве;
sync - для синхронизации файловых операций и состояния файловой системы.
Объединение блока средств навигации - несколько условно, так как ряд команд его служат также несколько иным целям. Важнейшие из них:
basename - служит для "вычленения" имени файла;
chroot - средство для смены корневого каталога;
pwd - определяет текущее положение в файловой системе;
su (от Set UID - получить идентификатор) - команда для получения полномочий другого пользователя:
tee - "расщепление" вывода команды на экран и в файл:
uname - для получения информации о системе;
who - команда для получения информации о зарегистрированных в данной системе пользователях.
Важнейшие команды блока для работы с контентом файлов (в первую очередь, разумеется, текстовых), таковы:
cat - многофункциональная команда для создания, просмотра и объединения файлов;
csplit - команда для разделения файлов на части, в качестве разделителя будет выступать строка, заданная как шаблон;
cut - "вытягивание" из заданного файла фрагментов строк;
fmt - нечто вроде форматирования абзацев текстового файла;
head - вывод первых (10-ти по умолчанию) строк файла;
od - просмотр файла в виде восьмеричных (по умолчанию) или иных других кодов;
sort - построчная сортировка содержимого файла;
split - разбиение файла на части заданного размера или количества линий;
tac вывод содержимого файла сзаду наперед (обратно cat);
tail - вывод нескольких (десяти по умолчанию) последних строк файла (обратно head);
wc - подсчет количества строк, слов или символов в файле.
С этим блоком команд связан самостоятельный пакет file, включающий единственную, одноименную, команду. Она позволяет детализовать тип регулярного файла (исполнимого, текстового и т.д) по т.н. "магической последовательности" байтов в его начале.
К coreutils по смыслу тесно примыкает пакет для поиска файлов - findutils. В его составе:
find - практически универсальное средство для поиска файлов и выполнения над найденным разнообразнейших операций;
xargs , используемая обычно в паре с командой find, позволяет применить некие команды к списку файлов;
locate - средство сканирования базы данных файловой системы с целью определения локации заданных файлов;
updatedb - средство обновления базы данных файловой системы, используемой командой locate .
Совершенно незаменим пакет grep (ftp://ftp.gnu.org/gnu/grep/). В его состав входят программы grep , fgrep и egrep ), предназначенные для поиска заданного текстового фрагмента (шаблона) в файлах.
Пакеты ed (ftp://ftp.gnu.org/gnu/ed/), sed (ftp://ftp.gnu.org/gnu/sed/ и gawk (ftp://ftp.gnu.org/gnu/gawk/) предназначены для весьма сложной обработки текстовых файлов. Первые два, в сущности, потоковые (неинтерактивные) текстовые редакторы. А gawk вообще представляет собой скорее язык программирования для написания сценариев обработки текстовых массивов. Теоретически, располагая мощным редактором интерактивным (типа emacs или vim ), без них можно было бы обойтись, но они столь широко используются во всякого рода системных сценариях, что практически оказываются необходимыми.
Аналогично и положение с пакетом groff (ftp://ftp.gnu.org/gnu/groff/), включающим множество средств сложного неинтерактивного форматирования текста. Вряд ли кто ныне, помимо впитавших привычку с молоком матери, будет использовать его в практической работе. Однако он оказывается необходимыми для функционирования системы документации, о которой речь пойдет чуть ниже.
Исходники всех программ, перечисленных выше (да и всех прочих, о некоторых их них будет говориться ниже) доступны в сети в архивированном (да еще и компрессированном) виде, и потому первое, что понадобится для работы с ними - это архиваторы и компрессоры. Список первых ограничивается программой tar (ftp://ftp.gnu.org/gnu/tar), тогда как компрессоров потребуется не менее двух: gzip (ftp://ftp.gnu.org/gnu/gzip/) и bzip2 (http://sources.redhat.com/bzip2/index.html), поскольку форматы их несовместимы (иногда встречающиеся архивы вида *.tar.Z могут быть распакованы программой gzip).
Наконец, группа пакетов, последняя по счету, но не по значению, - системы документации. Таковых в Linux широко используется две - традиционные для Unix man-страницы ftp://ftp.kernel.org/pub/linux/docs/manpages/ и разработанная в рамках GNU система info ftp://ftp.gnu.org/gnu/texinfo/. По содержанию они существенно перекрывают друг друга, и потому обычно могут выступать в качестве альтернативных. Однако полная документация к ряду программ проекта GNU доступна только в формате info . Примером тому - упоминавшийся выше загрузчик GRUB, man-страница которого содержит лишь минимум сведений.
Однако сами по себе системы документации, как ни странно, не содержат средств для ее чтения - для этого требуется специальная программа постраничного просмотра, так называемый pager (не путать с тем, чем лохи в песочнице ковыряются :-)). В Linux (а в след за ней и прочих Unix'ах) в качестве таковой утвердилась утилита less , входящая в одноименный пакет (http://ftp.gnu.org/gnu/less/), включающий, кроме того, утилиты lessecho и lesskey . Впрочем, утилита less выполняет и функцию просмотра содержимого текстовых файлов вообще, и потому вдвойне необходима.
Набор приложений, включенных в боевой набор пользователя, может показаться несколько аскетичным. Однако свою функцию - взаимодействие пользователя с остальным компонентами базовой системы - он обеспечивает с успехом. Хотя практически всегда он включает еще и текстовый редактор. Таковым обычно выступает Vim - универсальный инструмент юниксоида, имеющий аналоги во всех Unix- и Unix-подобных системах (http://www.vim.org). Впрочем, в Linux в качестве базового редактора он все чаще дополняется (а то и подменяется) более легким и простым в освоении редактором nano (http://www.nano-editor.org).
Это понятие почти полностью охватывается главной общесистемной библиотекой, каковой в Linux является glibc (ftp://ftp.gnu.org/gnu/glibc/), начальные сведения о которой были приведены выше. Она включает множество собственно библиотечных файлов вида lib*.so и так называемые заголовочные файлы (header-файлы) - своего рода оглавления, по которым в библиотеках отыскиваются требуемые функции.
Существуют попытки замены библиотеки glibc ее аналогами, пусть не столь функциональными, но более компактными, такими, как uClibc (http://uclibc.org/). Эта библиотека обычно используется в системах специального применения, например, во встроенных устройствах. Однако есть и базирующиеся на ней дистрибутивы общего назначения, например, один из вариантов LFS (Linux from Scratch) и разновидность CRUX.
Практически столь же обязательной, как и библиотека функций Си, оказывается библиотека свойств терминала ncurces (ftp://ftp.gnu.org/gnu/ncurses/) - ее используют очень многие консольные программы, readline () - именно эта библиотека отвечает за интерпретацию bash аргументов командной строки, и библиотека компрессирования - zlib (). Наконец, требуется также инструментарий для связывания программ с библиотечными функциями - libtool (ftp://ftp.gnu.org/gnu/libtool/).
Linux - система интернациональная. И эта ее особенность тоже требует специальной библиотеки - gettext (http://ftp.gnu.org/gnu/gettext/), обеспечивающей так называемую поддержку NLS (Native Language Support - то есть поддержка языков, отличных от американского английского).
Ознакомившись с приведенным нагромождением пакетов, разрабатываемых в рамках самостоятельных проектов, в большинстве случаев с разработкой ядра Linux никак не связанных, часто альтернативных, с дублирующими функциями, читатель вправе задать вопрос: и где же здесь обещанная системная целостность Base Linux? Постараюсь ответить.
Да, Base Linux не являет собой столь стройной картины, как, скажем, базовый комплект FreeBSD (и других BSD-систем), в которых ядро гармонично сочетается с утилитами обрамления, разрабатываясь одной командой, в рамках единого проекта. Тем не менее, все его компоненты вполне увязаны между собой. И даже если исторически они создавались до Linux, вне Linux и независимо от него, то уже на протяжении многих лет основной (или одной из основных) целевой платформой является именно Linux. Некоторые компоненты Base Linux жестко привязаны к версиям ядра, иные же достаточно быстро ориентируются на новые возможности, в них появляющиеся.
Кстати, и BSD-системы, не смотря на свое внутреннее единство, включают в себя "чужеродные компоненты", происходящие из тех же проектов GNU и FSF, наиболее показательным примером чего является компилятор gcc (GNU C Compiler) - точно то же, что используется и в Linux.
Что же до альтернативности многих пакетов Base Linux - так это неотъемлемая черта этой операционной системы. И потому ОС Linux - не только (а может быть, и не столько) ядро и набор базовых программ. Это, на мой взгляд, в первую очередь алгоритм для построения такого набора - это и есть тот самый четвертый вариант определения операционной системы, о котором было упомянуто в начале статьи.
Остается рассмотреть, как этот алгоритм - сборка системы воедино, - реализуется практически, и что для этого нужно. Существует три вида реализации сборки системы:
- прямая компиляция из исходных текстов;
- автоматизированная компиляция посредством специально предназначенных для этого систем;
- развертывание системы из прекомпилированных бинарных пакетов.
Прямая компиляция подразумевает ручную сборку каждого пакета в определенной последовательности, определяемой их взаимными зависимостями. Этот механизм требует дополнительного инструментария - так называемых средств разработки (хотя в данном случае они выступают в качестве средств сборки). В первую голову это компилятор языка C, на котором написана большая часть ОС Linux и программ для нее - gcc (ftp://ftp.gnu.org/gnu/gcc/).
Далее - средства обеспечения компиляции (линкер, ассемблер и т.д.), объединенные в два набора bin86 (http://www.cix.co.uk/%7Emayday/) и binutils . Последний пакет существует в двух вариантах - GNU (ftp://ftp.gnu.org/gnu/binutils/) и Kernel.org (http://www.kernel.org).
Затем - программа управления компиляцией, make (конкретно - GNU make, ftp://ftp.gnu.org/gnu/make/) и тесно с ней связанные утилиты autoconf (ftp://ftp.gnu.org/gnu/autoconf/) для построения средств автоматического конфигурирования при сборке, и automake (ftp://ftp.gnu.org/gnu/automake/) для автоматизации создания make-файлов, описывающих процесс компиляции. Кроме этого, практически необходимыми оказываются также лексический анализатор flex (ftp://ftp.gnu.org/gnu/non-gnu/flex/), синтаксический анализатор bison (ftp://ftp.gnu.org/gnu/bison/; иногда требуется также его прототип yacc - http://dinosaur.compilertools.net/, - для сборки некоторых программ необходим именно он) и макропроцессор m4 (ftp://ftp.gnu.org/gnu/m4/).
Механизм ручной сборки системы прекрасно описано Герардом Бикмансом в его знаменитом LFS Book (Linux From Scratch - что в данном контексте можно перевести как "Linux из кусочков", http://www.linuxfromscratch.org). Есть и прекрасный русскоязычный сайт Сергея Каминского, посвященный этой теме (http://lfs-ru.nm.ru/).
Сам по себе процесс сборки системы сводится к повторению трех волшебных слов для всех пакетов (/configure , make , make install ). Очевидно, что он требует наличия, кроме необходимых пакетов исходников, некоей Linux-системы - на диске или в виде LiveCD, - содержащей весь необходимый инструментарий. И при этом не обеспечивает контроля зависимостей пакетов - все они должны разрешаться вручную. И потому этот механизм применяется исключительно энтузиастами - и в основном в целях самообразования.
На практике же появляется резонное желание автоматизировать процесс сборки. Для этой цели разработано множество специальных систем, прототипом которых послужила система управления портами FreeBSD. Были и попытки прямого их переноса в некоторые дистрибутивы Linux. Кроме того, для многих из них существует система pkgsrc, разработанная в рамках проекта NetBSD как изначально кросс-платформенное средство, аналогичное портам. Но в большинстве случаев разработчики Linux-дистрибутивов шли своим путем: приняв основные принципы построения системы портов - автоматическое конфигуррирование, сборку и установку пакета, учет и контроль зависимостей, автоматическое их разрешение, - они создавали функционально аналогичные (или даже более богатые) собственные инструменты для этого.
Причиной такого подхода, кроме понятных амбиций майнтайнеров-линуксоидов, было также и различие моделей разработки Linux и BSD-систем (и, как следствие, их внутреннего устройства). Как уже было сказано ранее, BSD-системы в базовой своей части представляют (почти) органичные целостности, построение которых контролируется собственными механизмами (процедура make world со всеми ее вариациями). И система портов (или pkgsrc) в них выступает своего рода внешним придатком, призванным "прикрутить" к базису операционки надстройку из приложений сторонних разработчиков, не являющихся, собственно, частями данной ОС.
В Linux, как мы только что убедились, ситуация совершенно иная: там весь базис система насквозь альтернативен и, в сущности, сшивается из лоскутков (from Scratch). И потому естественным видится то, что механизм "портирования" можно распространить на всю систему.
В связи с этим наибольшую известность из всех портообразных систем для Linux получила система портежей дистрибутива Gentoo - именно в ней впервые, насколько мне известно, была реализована идея "сквозного портирования", вплоть до святого святых Base Linux - ядра. Кроме этого, портежи привнесли с собой изощренные средства автоматического построения зависимостей, основанные на "аккумулятивном эффекте" переменной USE.
Однако портежи Gentoo - далеко не единственная из портообразных систем мира Linux. В том же ряду можно назвать систему "волшебных заклинаний" (sorcery) из дистрибутива Sorcerer и его потомков (SourceMage и Lunar - в последнем она, правда, видоизменилась и получила собственное имя), система ports дистрибутива CRUX (наиболее близкая к FreeBSD-прототипу), ABS - Archlinux Building System - из одноименного дистрибутива, и еще несколько аналогичных.
Очевидно, что, поскольку при использовании любой портообразной системы происходит все та же компиляция из исходников, она предъявляет те же требования, что и механизм ручной сборки: наличие полного инструментария для оной. Плюс к тому: необходимо само по себе дерево портов (или как их ни назови - суть дела от этого не меняется) и специфичные именно для данной портообразной системы средства для работы с ним, перечислять, а тем более описывать которые было бы очень долго и скучно.
Наконец, установка системы из бинарников - то есть предварительно откомпилированных пакетов. Каковые, разумеется, также собираются из исходников (потому что, как сказал бы Вилли Старк, больше их просто не из чего собирать), но это - забота майнтайнера данного дистрибутива. То есть для пользователя отпадает необходимость иметь в своем арсенале тот самый инструментарий разработчика, о котором говорилось выше. Однако возникает потребность в другом - в средствах управления бинарными пакетами.
Средства эти столь многообразны, что говорить о них можно было бы долго - тем более, что прямого отношения к теме Base Linux они не имеют. Так что отметим только, что их наличие - необходимость для дистрибутива, распространяемого в пакетной форме, и отложим тему до следующего раза.
Итак, в ходе столь длинного разговора мы установили следующее:
- комплекс Base Linux имеет место быть в природе, по крайней мере во "второй" :-);
- комплекс этот насквозь альтернативен - почти каждый его компонент может быть заменен аналогичным по задачам;
- замена эта может быть выполнена как майнтайнерами дистрибутива, так и индивидуальными пользователями;
- каковые располагают возможностью скомпоновать Base Linux (почти) по собственному усмотрению.
Видимо, именно этим Linux и привлекает определенную категорию пользователей - возможностью соучастия в построении основы основ системы, недостижимую не то что в Windows, но даже в мире BSD с его камерным стилем разработки. Не зря дедушка русского линуксописания, Владимир Водолазкий, отметил в свое время, что быть просто пользователем Linux - скучно. От себя я добавлю: пожалуй, что и невозможно. Действительно, рано или поздно любой линуксоид становится творцом - по крайней мере, в масштабах своей локальной машины. В результате чего система становится похожей не на своего родителя (исходный дистрибутив), а, подобно собаке, на своего хозяина (сиречь, пользователя). И очень многие пользователи со временем приходят и к сборке собственной Linux-системы - или, по крайней мере, проходят эту стадию, как нечто вроде болезни роста (своего, информационного). А некоторые в конце концов на базе таких самостройных систем создают в конце новые, собственные, дистрибутивы. Впрочем, это уже отдельная история, которая будет предметом следующей статьи.
Автор: Алексей Федорчук
Источник: www.citforum.ru
|