Алексей Федорчук
Изложение воззрений кота Manual’а на те аспекты работы с deb-пакетами, которые влияют на индивидуализацию системы. И первая их часть будет посвящена общим вопросам. В ней будет говориться о пакетах вообще и deb-пакетах в особенности. Читатель, знакомый с этими понятиями, может спокойно её пропустить.
Пакеты, зависимости, библиотеки
Пакеты — это своего рода программные кванты, на которые делится система или дистрибутив. Это могут быть и простые монофункциональные утилиты (например, строчный текстовый редактор ed
или архиватор tar
), более или менее обширные наборы функционально связанных программ (скажем, coreutils) или составные части огромных программных комплексов (примером чему — рабочая среда Cinnamon, которая будет предметом специального рассмотрения).
Термин пакет (английское package) употребляется в двух смыслах: как авторский набор исходных текстов, созданный разработчиком программы, и как комплект скомпилированных из него исполняемых программ и всех их служебных файлов, собранный майнтайнерами дистрибутива или вообще третьими лицами. Пакеты в первом смысле называются исходниками или вообще «сырцами» (от английского Source), во втором — бинарниками. В этом manual’е речь пойдёт почти исключительно о пакетах во втором понимании этого термина.
Бинарные пакеты специфичны для семейств некогда родственных дистрибутивов, почему часто говорят о системах rpm based или deb based. Но даже если они собраны в одном формате (например, rpm или deb), бинарные пакеты из разных дистрибутивов далеко не всегда совместимы в рамках одной системы. Впрочем, к формату deb, который здесь рассматривается, это относится в наименьшей степени: например, пакеты для всех дистрибутивов семейства Ubuntu сохраняютпочти полную бинарную совместимость внутри него, а иногда — с пакетами прародительского Debian’а и его прямых клонов.
Ключевым для бинарных, или дистрибутивных, пакетов является понятие зависимостей. Суть его в том, что пакет packagename1 для сборки, установки и (или) функционирования требует наличия в системе пакета packagename2, тот, в свою очередь, может потребовать пакета packagename3, и так далее.
Различаются зависимости «жёсткие» и «мягкие». Удовлетворение первых абсолютно необходимо для сборки и функционирования данного пакета. Так, практически любая программа использует главную системную библиотеку glibc
, любое приложение для системы X — одну из главных Иксовых библиотек, xlib
или xcb
, любая интегрированная рабочая среда — одно из двух основных семейств высокоуровневых библиотек, Qt/KDE или Gtk.
«Мягкие» зависимости данного пакета не критичны для его функционирования — удовлетворение их лишь добавляет ему дополнительные функции (например, печати и сканирования для офисных и графических приложений) или возможности (скажем, доступ к файлам данных определённых форматов для той же графики или мультимедиа).
В deb-формате бинарных пакетов предусмотрено более дробное разделение «мягких» зависимостей, но об этом подробнее будет говориться чуть позже. А пока замечу, что часто приходится учитывать и так называемые конфликтующие зависимости — то есть альтернативные по назначению пакеты, не способные ужиться в одной системе.
Понятие зависимостей пронизывает насквозь UNIX-совместимые системы, и особенно важно для свободных их представителей. Ибо традиционная модель разработки UNIX-программ (то, что задумчиво именуют UNIX Way) характеризуется ярко выраженным стремлением не множить сущности без крайней необходимости. Или, говоря попросту, не изобретать велосипеды. Ведь все программы, вне зависимости от их назначения, неизбежно должны выполнять некоторые однотипные действия, как то: открыть файл, записать его, вывести на экран его содержимое, и так далее. Сущность таких действий не меняется, что бы программа ни делала. И потому нет никакого смысла программировать такие манипуляции каждый раз заново.
Вот их, как правило, поддаваясь смертному греху лености, и не программируют «с нуля». А объединяют соответствующие директивы в отдельные программные комплексы, именуемые библиотеками (libraries). Сами по себе они к автономному исполнению не предназначены. Однако любая программа, при необходимости совершить одно из типовых действий, вызывает из такой библиотеки некий фрагмент кода, содержащий требуемую последовательность директив.
Библиотеки обычно привязаны к определённым языкам программирования, синтаксису которого подчиняются описания директив, так называемых функции. Поскольку наиболее употребимым в UNIX-системах и их приложениях является язык C, то его функции и требуются чаще всего. Они собираются в главную системную библиотеку, которая почти во всех дистрибутивах Linux именуется glibc
.
Однако главной системной библиотекой список не исчерпывается. В UNIX-подобных системах при создании пользовательских интерфейсов используются библиотеки свойств терминала (например, ncurces
) для консольных программ и библиотеки, описывающие процедуры отрисовки окон и управления ими — для графических программ системы X, библиотеки интерфейсных элементов и графических примитивов более высокого уровня (Motif, Qt, Gtk), библиотеки описания графических и мультимедийных форматов файлов и тому подобные «сборники». Иными словами, существует тенденция к вынесению в разделяемые библиотеки всех повторяющихся действий и элементов, какие только возможно.
Если библиотек, используемых в программах для консольного режима, не так много, они достаточно универсальны и легко поддаются учёту, то с библиотеками для обеспечения графического режима существенно сложнее. Даже простое перечисление их заняло бы немало места. Поэтому ограничусь упоминанием главных из них, на которых базируются рабочие среды (они же именуются десктопами, DE) и их штатные приложения.
Большая часть распространённых десктопов использует библиоотеки Gtk 3-й и, реже, 2-й верси. В их числе Cinnamon, LXDE, MATE, Xfce, Unity и, наконец, GNOME 3 (далее именуемый просто GNOME, поскольку вторая ветка этой среды вымерла соответственно. К ним же примыкает). Последний десктоп для своей работы требует также собственных библиотек GNOMElibc.
На библиотеке Qt основана среда KDE, которая также не живёт без собственных библиотек из набора KDELibs. Чистая Qt используется в настоящее время только в десктопе LXQt. Однако в будущем ожидается переход на эту библиотеку десктопа Budgie. Также на Qt основана среда Unity 8, в том числе и её десктопный вариант, который, правда, пока назвать работоспособным язык не поворачивается.
Надо заметить, что в последнее время возник и другой подход к разрешению запивсимостей: упаковка исполняемых модулей программ вместе со всеми необходимыми для их работы библиотеками в единый, самодостаточный пакет. Таковы системы Snap (изначально созданныая для Ubuntu, но ныне способная работать и в более иных дистрибутивах) и от рождения кросс-дистрибутивная система Flatpak. Однако ни та, ни другая всенародного признания пока не получили, так что речи о них в этом Manual’е не будет.
Формат deb-пакетов
Формат пакетов deb был разработан ещё в прошлом тысячелетии для дистрибутива Debian и унаследован от него Ubuntu, во многом предопределив успех последней. А вслед за ней — и удачливость многих её клонов. Почему deb-формату и следует уделить некоторое внимание.
Пакет deb-формата — архивный файл (собранный утилитой архивирования ar
), включающий три компонента. Первый — это файлик debian-binary
, не содержащий ничего, кроме номера версии deb-формата (в данный момент — 2.0).
Второй файл носит имя data.tar.xz
и, как легко догадаться, представляет собой tar-архив, сжатый утилитой xz
. Содержимое архива — скомпилированные исполняемые бинарники и необходимые им для работы компоненты (библиотеки, конфиги, документация и так далее). Иными словами, все компоненты, которые при установке пакета будут инкорпорированы в файловую иерархию целевой системы.
Третий файл именуется control.tar.gz
и представляет собой архив файлов, содержащих всякого рода метаинформацию — описание пакета, его зависимости, классификационную принадлежность, приоритет и так далее (файл control
), контрольные суммы всех исполняемых бинаников (файл md5sums
), сценарии, выполняемые при установке и удалении пакета (preinst
, postinst
, prerm
и postrm
).
Зависимости в терминах deb-пакетов имеют несколько градаций: обязательные (depends
), рекомендуемые (recommends
), предлагаемые (suggests
), конфликтующие (conflicts
). Первая градация — это обычные «жёсткие» зависимости, без удовлетворения которых пакет либо не будет работать, либо вообще не установится. С градацией последней тоже понятно — это, так сказать, анти-зависимости.
Ну а зависимости рекомендуемые и предлагаемые — это две разновидности «мягких» зависимостей. Разница между ними в том, что рекомендуемые пакеты обеспечивают «зависимому» пакету дополнительные функции (например, поддержку мыши в консольных приложениях), а пакеты предлагаемые предоставляют дополнительные возможности, вполне вероятно, полезные, но не жизненно необходимые (например, документацию, в том числе на не-английских языках).
То есть первая категория «мягких» зависимостей как бы более нужная, нежели вторая. Впрочем, таково субъективное мнение майнтайнера конкретного пакета — вполне возможно, что у применителя будет по этому поводу мнение более иное. И потому и пакетный менеджер apt, и его графическая «морда» Synaptic, устанавливающие зависимости автоматически, в в большинстве deb based дистрибутивов по умолчанию не делают этого ни для рекомендуемых, ни, тем более, для предлагаемых пакетов, а лишь выводят их список, дабы применитель сам принял решение по данному вопросу.
Кроме того, спецификой deb-пакетов является ещё и существование так называех пред-зависимостей (pre-depends
) — при их нарушении установка пакета даже не может начаться, ибо их наличия требует пре-инсталляционный сценарий «зависящего» пакета. Впрочем, с точки зрения пользователя они немногим отличаются от обычных зависимостей типа depends
.
Кроме зависимостей, для пакетов deb-формата важно также понятие их приоритета. Оно отражает степень необходимости пакета для функционирования системы, например: обязательный (required
), без которого работа системы невозможна, основной (base
) и важный (important
), также оказывающиеся практически необходимыми, стандартный, то есть имеющийся практически в любой полнофункциональной Linux-системе, дополнительный (optional
) — тут уж степень важности каждый должен решать для себя.
Как это принято в мире Open Source, все бинарные пакеты (и пакеты deb-формата тут не исключение) сопровождаются исходными текстами, доступными из соответствующего репозитория дистрибутива. И здесь deb-формат проявляет свою специфику: каждый пакет в исходниках обычно включает три файла — packagename.orig.tar.gz
, packagename.dsc
и packagename.diff.gz
.
Первый — самый обычный тарбалл исходных текстов авторского пакета, что подчеркивается словом orig в его имени: формат архива, имя и система нумерации версий также совпадают с таковыми авторского пакета. Файл packagename.dsc
содержит в себе всю метаинформацию, необходимую для правильного построения из него бинарного deb-пакета. А packagename.diff.gz
— это те изменения исходного кода, которые вносятся для адаптации пакета непосредственно к данному дистрибутиву. Если таких изменений не потребовалось (или если пакет писался именно для данного дистрибутива), он может и отсутствовать.
Статус пакетов
В системах пакетного менеджмента deb based дистрибутивов, в том числе и в Mint, пакеты объединяются в категории, секции и группы. Список категорий включает следующие пункты:
- Установленные пакеты — очевидно из названия;
- Обновляемые пакеты — установленные пакеты, для которых в репозитории доступны более новые версии;
- New Packages — пакеты, добавленные в локальный кэш после последней его очистки;
- Неустановленные пакеты — пакеты, отсутствующие в системе, но доступные из репозиториев;
- Виртуальные пакеты — не существующие пакеты, указывающие на другие пакеты, которые нужно использовать для тех или иных задач;
- Задачи (Tasks) — группы пакетов (метапакеты), которые предоставляют лёгкий способ выбора заранее сформированного набора пакетов под определённую цель.
В секции пакеты группируются по назначению: программы для администрирования, базовые пакеты, текстовые редакторы, и так далее.
Группы представляют собой разделы официального репозитория. В дистрибутивах, основанных на Ubuntu, они таковы: main
, restricted
, universe
, multiverse
, о чём речь пойдёт позднее.
Каждый пакет в терминологии имеет основной статус, обозначаемый строчной литерой; в их число входят:
i
(от install) — установленный пакет;
p
(от purge) — пакет не установленный или деинсталлированный «вчистую» (то есть с удалением его конфигурационных файлов);
c
(от clean) — пакет, деинсталлированный с сохранением конфигурационных файлов;
v
(от virtual) — виртуальный пакет.
Кроме того, пакеты могут иметь один из следующих дополнительных статусов, хотя это и не обязательно:
A
(от Auto) — установленный автоматически, как зависимость другого пакета; пакеты, не имеющие статуса A
, считаются установленными вручную;
h
(от hold) — пакет с фиксированной версией (то есть не подверженный апгрейду);
u
(от unpacked) — пакет распакованный, но не установленный;
H
— «недоустановленный» пакет;
C
— пакет установленный, но не настроенный;
B
— «сломанный» пакет, то есть установленный с нарушением зависимостей.
Обращаю особое внимание на пакеты, имеющие статус A
: они устанавливаются вместе со своими зависимостями и могут быть удалены только вместе с ними. Правда, как мы увидим дальше, статус установленного пакета может быть изменён, и тогда он станет доступным для индивидуального удаления.
В сущности, все действия по управлению пакетами в дистрибутивах, использующих deb-формат, сводятся к изменению их статуса. И делается это с помощью инструментов текстового режима (утилиты dpkg
, gdebi
, apt
) или их графических фронт-эндов («морды» для Gdebi, Qapt, Synaptic).
Средства для работы с пакетами
Инструментарий для работы с пакетами можно разделить на пять групп:
- установщики пакетов;
- оболочки для них;
- менеджеры пакетов;
- их графические фронт-энды;
- центры приложений.
Первая группа — это низкоуровневые утилиты для работы с единичными пакетами: их установки, удаления, etc. В нашем случае эту роль выполняет семейство утилит dpkg
. Отслеживание зависимостей здесь выполняется на уровне удовлетворения или неудовлетворения, попыток автоматического разрешения зависимостей не предпринимается.
Оболочки для установщиков пакетов выполняют те же самые функции, что и они сами, посредством как прямых команд (утилита gdebi
), так и средствами графического интерфейса. К числу последних принадлежат Gdebi (использующая Gtk), Gdebi-kde (для одноимённой среды), Qapt, основанная на библиотеке Qt. Сдежует заметить, что все эти оболочки не только отслеживают выполнение или нарушение зависимостей, но и предпринимают попытки их разрешения, более или менее успешные, в зависимости от обстоятельств.
Менеджеры пакетов работают уже не с единичными пакетами, а с их репозиториями. И, кроме перечисленных функций, их непременной обязанностью является не только отслеживание зависимостей, но и их автоматическое, по возможности, разрешение. В большинстве deb based дистрибутивов эту роль выполняет семейство утилит APT, из которых наиглавнейшей нынче является одноимённая утилита — apt
.
Четвёртая группа — графические фронт-энды для менеджеров пакетов. Нынче она представлена программой Synaptic; её аналог для среды KDE, Muon, назвать вполне функциональной нельзя.
Что же касается пятой группы — это самые высокоуровневые программы, в которых прозрачно для применителя интегрированы функции поиска пакетов в Сети, подключения к содержащим их репозиториями и собственно пакетный менеджмент. Название её заимствовано от Центра приложений Ubuntu — первого представителя этой группы. Хотя в некоторых случаях программы этой группы могут оказаться полезными, автору этих строк они представляются избыточными, и речи о них в данном Manual’е не будет. Остальные же инструменты работы с пакетами будут рассмотрены в его следующих частях.
Алексей извините может немного не в тему, но хотелось бы найти на этом сайте подробное описание создания переносимых пакетов подобно portable приложениям в линукс с помощью Snap, AppImage, Flat, FATElf. На сайте того же разработчика Snap описан процесс создания таких приложений с помощью Snap однако довольно скудно, кроме того он описывает использования Snap сразу при установке приложений, хотелось бы узнать если Вы в курсе данного вопроса можно ли сначала в линукс установить пакеты а затем сделать их преносимыми (запускаемые) в др линукс системах. Кроме того хочу спросить у Вас существует ли портированная версия менеджера tarball пакетов из ArchLinux для Debian? И еще один вопрос кроме специфичных пакетов для каждого линкса существуют уже готовые бинарники пакетов которые просто запускаются в линуксах где и как их искать ?