14 лет назад 16 августа 2004 в 2:14 67

Речь в этой статье пойдет об инсталляции программ в Linux. Только сначала придется принести свои извинения той части аудитории, которой многое сказанное ниже покажется банальным (таким оно, кстати, и является на самом деле). Дело в том, что успехи известной корпорации из Рэдмонда превращают эти банальности практически в terra incognita для подавляющего большинства пользователей и даже для некоторой части программистов.

БАНАЛЬНОСТЬ №1: НАЧНЕМ С ОС
Первой банальностью будет определение операционной системы как совокупности программных средств, обеспечивающих запуск пользовательских приложений. Определение заведомо неполное, но для начала – достаточное.

Исходя из него, мы можем сделать однозначный вывод: то, что называется MS Windows, несколько выходит за эти рамки, а если под Linux понимать ядро, то это заведомо меньше. Даже если в понятие “Linux” включить базовые средства системы (по поводу состава которых также не существует единого мнения), эквивалентности все равно не получится. Таким образом, банальность №1 имеет два следствия:

– сравнение MS Windows и Linux почти всегда неправомерно, поскольку, с одной стороны, мы видим единый продукт самой богатой в мире корпорации, а с другой – более или менее полный набор разнородных продуктов, собранных воедино одной, сравнительно небольшой компанией, а то и отдельным энтузиастом;

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

Забегая вперед, можно сказать, что так оно и есть: именно по способу управления составом ПО дистрибутивы Linux прежде всего и различаются.

БАНАЛЬНОСТЬ №2: ЧТО МЫ ЗАПУСКАЕМ
Все, что мы запускаем (в любой ОС), фактически является скриптом или исполняемым двоичным файлом. Первый – набор команд (обычно – в виде текста), исполняемых определенной программой – интерпретатором (от простейшего командного до изысканных Python и виртуальной Java-машины), второй – набор байтов, непосредственно используемых как инструкции и/или данные процессором вычислительной системы.

По поводу первого можно сказать, что интерпретируемые скрипты – неиссякаемый источник гордости приверженцев UNIX (и Linux, в частности). В настоящее время как минимум два мощных интерпретатора де-факто являются частью базовой системы: командный интерпретатор shell (в нескольких ипостасях) и Perl. Почти все создатели дистрибутивов включают в их состав Tcl/Tk, Python, PHP и Java. Многие – Ruby, Calm, etc.

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

А вот по поводу второго… Разумеется, ядра у MS Windows и Linux – принципиально разные. Более того: у одного Linux ядер огромное количество. Мало того, что авторы-энтузиасты денно и нощно совершенствуют свое детище, так они еще и всякому конечному пользователю предоставляют возможность собрать ядро самому.

Все, наверное, помнят стенания Microsoft по поводу того, как сложно было обеспечить возможность запуска DOS-приложений под Windows. Поэтому и не приходится удивляться непереносимости исполняемых двоичных файлов под Linux. Особенно если учесть тот факт, что наряду с ядром изменяются также базовые библиотеки, компиляторы и т. д. Причем часто – независимо друг от друга.

БАНАЛЬНОСТЬ №3: ОТКУДА ЧТО БЕРЕТСЯ
Итак, исполняемый двоичный файл, как правило, учитывает особенности ядра ОС, с которым ему предстоит взаимодействовать. “А при одном и том же ядре переносимость-то будет полная?” – спросит пользователь. Увы. Очередная банальность состоит в том, что современные программы (назовем так для краткости двоичные файлы, отличая их таким образом от скриптов), как правило, используют разделяемые библиотеки: файлы, представляющие собой хранилища подпрограмм, предназначенных для “коллективного” использования.

Программ, вообще не использующих библиотеки, – единицы. Но и для программ, библиотеки использующих, существует возможность освободиться от “библиотечной” зависимости. Для этого нужно все используемые библиотечные модули “присоединить” к телу программы. Называется это статической линковкой (в отличие от линковки динамической, используемой обычно по умолчанию). Таких программ уже заметно больше. В некоторых случаях (использование приложением уникальных или просто мало распространенных библиотек) такое решение вполне себя оправдывает.

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

Большинство же программ для всех современных ОС используют общие (правильнее – динамически разделяемые) библиотеки. И эта банальность имеет далеко идущие последствия, весьма осложняющие построение Linux-системы. Дело в том, что набор базовых разделяемых библиотек для MS Windows принадлежит одному производителю, жестко контролирующему заодно и разнообразие ядер ОС.

В Linux же разделяемые библиотеки создаются разными производителями, как правило – независимо, и часто – асинхронно. Для полноты картины напомним, что некоторые библиотеки зависят от ядра, которое, в свою очередь, как и большинство остальных библиотек, зависит от библиотеки базовой.

И это еще не все. Программы могут использовать в своей работе какие-то аспекты функционирования ОС, не регламентируемые ядром Linux. Это могут быть “пути” (path) по умолчанию для конфигурационных файлов, файлов протоколов, значения переменных окружения… Да мало ли, что может придумать программист, фантазия которого не ограничивается ни заказчиком, ни единым планом работ с коллегами? И возможно ли преодолеть все эти “мириады” несоответствий?

РЕАЛИИ
Совершенно очевидно, что разнообразие ПО, создаваемого даже не для Linux – для UNIX в рамках Open Source, есть и будет всегда. Следовательно, для использования этого разнообразного ПО в рамках одной системы нужно эту систему регламентировать и “подогнать” под нее отобранный софт (благо он доступен в виде исходных текстов). Эту задачу, собственно, и решают создатели дистрибутивов Linux. Начинается все с регламентации системы.

Принимается решение:
– какой использовать способ загрузки (BSD-style у Slackware и большинства source-based-дистрибутивов, SysV-style у Debian и большинства rpm-based-дистрибутивов);
– как организовать файловую систему, где хранить те или иные файлы;
– как ограничить разнообразие ПО (универсальный или проблемно-ориентированный дистрибутив).

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

Нужно сказать, что вопрос этот намного важнее для Linux, чем для MS Windows. Девственно чистый список установленных программ в свеже-инсталлированной Windows XP, безусловно, радует глаз. В аналогичной по составу Linux-системе список инсталлированных программ легко может перевалить за сотню.

Объяснение элементарно: базовый состав Windows XP (включающий, разумеется, и графическую среду) редакции не подлежит, тогда как в Linux к инсталлированным относятся все компоненты, включая ядро. Кажущейся простоте MS Windows противопоставляется, таким образом, полный контроль над составом системы.

Вернемся, однако, к вариантам распространения программ под Linux. На “верхнем” уровне их, собственно, всего два:
– в виде двоичных файлов, представляющих собой архивы готовых к использованию, уже скомпилированных программ и библиотек;
– в виде исходных текстов, компилируемых, “превращаемых” в готовые к использованию файлы уже в системе конечного пользователя.

СРАВНИМ
Именно по этому признаку дистрибутивы Linux делятся на “прекомпилированные” (pre-compiled) и “самосборные” (source-based). Прекомпилированные (Debian, Slackware, RedHat/Fedora, Mandrake, SuSe) распространены шире. Возможно, это объясняется очевидным сходством процесса инсталляции в них с таковым под MS Windows: и в том и в другом случае инсталляция представляет собой прежде всего переписывание нужных файлов в нужное место.

Основные достоинства:
– простота инсталляции;
– скорость;
– качество, с учетом качества исходного продукта и компетенции мейнтейнера, компилировавшего программу;
– наличие GUI-средств управления системой установки пакетов;
– потенциальная возможность создания коммерческого (закрытого) программного обеспечения для данной системы. Так называемые “драйвера” для Linux, прилагаемые к некоторым изделиям производителями hardware, на самом деле оказываются модулями, скомпилированными для одной или нескольких версий конкретных Linux-дистрибутивов, которые производитель почему-то посчитал наиболее распространенными. Возможность самостоятельной компиляции ядра, имеющаяся даже в прекомпилированных дистрибутивах, в данном случае в расчет не принимается.

Список недостатков, к сожалению, тоже не мал:
– полная зависимость от мейнтейнера в части состава как отдельного пакета, так и дистрибутива в целом (вы ведь не забыли о взаимных зависимостях библиотек и программ?);
– возможность использовать почти исключительно пакеты, предоставляемые составителем дистрибутива;
– проблематичность сокращения состава системы ниже уровня, понимаемого авторами как “базовый”;
– трудность модификации системы сверх того, что предполагалось теми же авторами.

“Самосборные” дистрибутивы (Gentoo, Arch, CRUX) обычно оперируют архивами дистрибутива программного продукта в том виде, в каком их создал автор (или авторы) и собственными управляющими файлами (пакетами, портами, портежами), которые подготавливаются авторами дистрибутива системы или их единомышленниками.

Управляющие пакеты нужны для того, чтобы:
– проверить целостность исходного дистрибутива;
– убедиться в наличии в системе необходимых компонент;
– модифицировать, если нужно, исходный дистрибутив;
– выполнить сакраментальное configure; make; make install, что в переводе на обычный язык означает: сконфигурировать в соответствии с пожеланиями и составом системы, создать, установить;
– занести информацию об инсталляции в таблицы системы контроля за составом установленного ПО.

Достоинства:
– возможность полного контроля за процессом инсталляции. Именно возможность, а не контроль, поскольку никаких вопросов/ответов и тем более меню в ходе инсталляции вам не предложат: вы можете разобраться с командным файлом из состава пакета, но это – ваше личное дело;
– большая гибкость, поскольку программа компилируется с учетом реальной целевой системы и ваших пожеланий, выраженных в форме настроек системы инсталляции и модификации командного файла;
– возможность использования одних и тех же исходных дистрибутивов программ в различных source-based-системах (не только Linux, но и, скажем, Free BSD, система портов которой и послужила прообразом всех обсуждаемых);
– к косвенным достоинствам можно также отнести подготовку пользователя к самостоятельной компиляции программ и модификации системы: наглядность процесса инсталляции наводит на мысль о возможности активного вмешательства в этот процесс.

К недостаткам обычно относят:
– несколько большие потери времени на инсталляцию (компиляция X-Window легко может отнять у вас целый день, а то и два);
– скромные размеры дистрибутива, обычно включающего в себя только прекомпилированные базовые пакеты, но не включающего дистрибутивы программ;
– отсутствие (возможно, временное) GUI-средств управления.

Что касается количества программ, доступных в рамках той или иной системы, то оно, как правило, не вызывает нареканий: более, чем достаточно. Только если с дистрибутивом Mandrake пользователь получает несколько дисков, заполненных уже готовыми к использованию пакетами, то обладатель CRUX после инсталляции располагает только базовой системой, дистрибутивы же программных пакетов и pkg-файлы ему предлагается добыть самому.

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

Аналогичная ситуация складывается и в отношении зависимости от доступа к Сети. “Свежий” прекомпилированный дистрибутив в таком доступе, как правило, не нуждается. Но чем дальше от “рождения”, тем больше вероятность того, что попытка “проапгрейдить” через Сеть даже весьма скромный по размерам пакет в рамках Debian или воспользоваться потрясающим (кроме шуток) богатством ALT линуксовского Sisyphus закончится весьма и весьма солидным объемом загрузки.

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

ДЕТАЛИ
Теперь о том, чем оборачиваются перечисленные достоинства и недостатки на практике.
Изначально все утилиты управления системами инсталляции – консольные приложения, и только в этом качестве они демонстрируют все свои возможности. Отсутствие GUI-оболочки для них в source-based-дистрибутивах не удивляет: базовая часть этих систем подчас вообще не содержит X-Window.

А вот прекомпилированные дистрибутивы подобные GUI-оболочки содержат. Более того, аналогичные программы входят как в Gnome, так и в KDE. Но самым приятным является то, что эти программы обеспечивают унифицированный интерфейс к нескольким системам управления прекомпилированными пакетами. Так, KPackage используется и в Debian, и в RedHat.

Тот факт, что состав прекомпилированного пакета определяется исключительно мейнтейнером, иногда может порядком испортить впечатление. Хрестоматийным примером является установка MidNight Commander (UNIX-родственника канонического Norton Commander). Данная программа может использоваться как в графической, так и в консольной среде. Именно на этом основании попытка установить MidNight Commander, как правило, влечет за собой установку X-Window и базовых библиотек Gnome, если они не были установлены до этого.

Это, в свою очередь, может быть совершенно излишним для, скажем, рабочей станции с VGA-адаптером и 12″ монитором. Надо признать, что MidNight Commander – не исключение. Список консольных утилит, “дуальный” характер которых не позволяет инсталлировать их без установки компонент графической среды, MidNight Commander, к сожалению, не исчерпывается.

Любая программа допускает при ее компиляции большее или меньшее число опций. Используя прекомпилированный дистрибутив, мы полагаем, что мейнтейнер имеет сходные с нами пристрастия и потребности. К счастью, чаще это соответствует действительности, но случаются и досадные “промахи”.

Вот, к примеру, список возможностей, которые я использую в своем любимом редакторе vim и которых он не имел изначально по милости мейнтейнера:
– возможность работать с текстами в кодировках win-1251, koi-8, utf с переключением “на лету”;
– стабильное поведение командных клавиш вне зависимости от активной раскладки клавиатуры;
– встроенные интерпретаторы python и perl;

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

Отсутствие нужной программы в наборе прекомпилированных пакетов дистрибьютора не нужно рассматривать как “обстоятельство непреодолимой силы”. Просто не стоит пытаться воспользоваться rpm(deb)-файлом иной версии или из другого дистрибутива – это действительно проблематично. Разумнее посетить сайт программы, загрузить архив дистрибутивного набора и собрать приложение самому. Вполне вероятно, что вышеупомянутой сакраментальной фразой configure; make; make install обойтись не удастся. Начать придется с ./configure -help.

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

В части создания проблемно-ориентированных и просто “аскетических” систем прекомпилированные дистрибутивы заведомо проигрывают самосборным. Мало того, что последние компактнее (за счет исключения каталогов doc и info , например), так они еще и свободны от навязчивой системы проверки зависимостей, как правило, допускают существование без X-Window, да и вообще проще и “прозрачнее”.

ХИТРОСТИ
Система контроля зависимостей прекомпилированных пакетов не так умна, как может показаться на первый взгляд. Первый ее изъян заключается в том, что она работает для всех инсталлируемых пакетов, тогда как практически необходима только для наборов исполняемых двоичных файлов, ссылающихся на разделяемые библиотеки. Набору скриптов, скажем, может быть отказано в инсталляции только потому, что в системе установлена другая версия интерпретатора. Почти наверняка эти скрипты будут работать и с наличной версией, но для этого нужно игнорировать несоблюдение зависимостей. И такая возможность существует.

Второй изъян системы зависимостей заключается в том, что она опирается на имена файлов пакетов, а имена эти могут быть различными даже для абсолютно идентичных пакетов разных дистрибутивов. И в этом случае можно попытаться игнорировать несоблюдение зависимостей. Такая “насильственная” инсталляция допустима только после анализа состава пакета: уверенность в том, что инсталляция, как минимум, не нанесет ущерба уже инсталлированному ПО, лишней никогда не будет.

Если пакет “чужого” дистрибутива предполагает отличную от вашей организацию файловой системы, то инсталлировать его, вероятнее всего, не следует. Ни к чему, скажем, помещать исполняемый файл в каталог /opt/bin, если этот каталог не включен в переменную PATH. Это не означает, однако, что нельзя “вручную” извлечь файлы пакета и поместить их в соответствующие каталоги вашей системы. Для неисполняемых файлов и скриптов эта операция абсолютно безопасна.

Нужно только учесть, что она, разумеется, не оставит соответствующей записи в таблицах контроля за инсталлированным ПО. Хорошим подспорьем в “борьбе” с прекомпилированными пакетами могут стать утилиты, разработанные “сторонними” (относительно авторов системы инсталляции) производителями. Одна из них – make_uninstall Кента Роботи (ftp://ibiblio.org/pub/Linux/utils/package).

Утилита позволяет взаимно преобразовывать пакеты форматов deb, rpm, tgz. Создавать их из содержимого каталогов, вести собственный протокол установленного ПО. Нетрудно догадаться, что с ее помощью можно и “реорганизовать” пакет “чужого” дистрибутива так, что и файлами его удастся воспользоваться, и система контроля инсталляций примет его как “родной”.

Все перечисленные операции нетривиальны. В их ходе вы можете столкнуться с необходимостью изменения владельцев инсталлируемых файлов и прав доступа к ним, настроек системы контроля за инсталляцией или даже редактирования mku (make_uninstall), представляющей собой скрипт командного интерпретатора. Скучать, одним словом, не придется. А вы думали, что Linux – скучная система?

Тем, кто предпочитает source-based-дистрибутивы, можно посоветовать почаще обращаться к командным файлам инсталляции и патчам, предлагаемым мейнтейнерами. Причем не только вашего дистрибутива. Патчи Gentoo, например, снискали заслуженную славу исключительно рациональных. Безусловно, иногда трудно определить, является строка инсталляционного скрипта или патча “подгонкой” под конкретный дистрибутив или реальным улучшением. Зато интересно. К тому же никто не утверждал, что расширение source-based-дистрибутива – это просто.

ВЫВОДЫ
– Инсталляция ПО в Linux может быть достаточно сложной и сложность эта естественна, поскольку определяется многообразием систем на базе Linux и наличием в их составе множества компонентов самого различного происхождения;
– Инсталляция программ в дистрибутивах с прекомпилированными пакетами не вызывает ни малейших затруднений до тех пор, пока вам не потребовался пакет, отсутствующий на дистрибутивных дисках или вы не занялись обновлением системы. Достаточно близкая аналогия с MS Windows: либо все работает “само”, либо ваших знаний заведомо недостаточно для исправления ситуации.
– Инсталляция программ в source-based-дистрибутивах наиболее эффективна, но требует некоторого уровня подготовки. Этот путь более всего соответствует духу Open Source, хотя и может оказаться достаточно трудоемким. Оптимальным сочетанием, очевидно, можно считать установку из прекомпилированных пакетов source-based-дистрибутива базовой системы, X-Window и основных библиотек KDE или Gnome (о вкусах не спорят), тогда как “персональное” ПО лучше собирать самостоятельно.