Мефодий нашёл в Интернете пакет с заинтересовавшей его программой в подходящем формате rpm
и решил попробовать его установить.
Для установки и удаления пакетов нужны права администратора — это серьёзные изменения в системе.
[root@localhost RPMS.local]# rpm -i xsltproc-1.0.32-some1.i586.rpm
ошибка: неудовлетворенные зависимости:
libxslt = 1.0.32-some1 нужен для xsltproc-1.0.32-some1
[root@localhost RPMS.local]#
Пример 8. Пакет не установлен из-за неудовлетворённых зависимостей
Однако rpm
отказался выполнять установку, ссылаясь на зависимость от другого пакета. Здесь Мефодий впервые столкнулся с тем, что пакеты — не всегда (точнее, почти никогда) бывают независимы от имеющейся системы. В разделе Package..Архив файлов уже говорилось о том, что для работы программы нужны различные ресурсы, причём несколько программ могут нуждаться в одном и том же ресурсе. В последнем случае общий ресурс может оказаться в отдельном собственном пакете (чтобы не включать его сразу в несколько), и этот пакет должен быть установлен в системе, чтобы заработали нуждающиеся в нём программы. Потребность пакета в ресурсах, находящихся в другом пакете, называют зависимостью этого пакета от другого. В процедуре установки rpm проверяет, все ли зависимости устанавливаемого пакета удовлетворены (т. е. все ли необходимые пакеты уже установлены в системе), и если чего-то не хватает — прекращает установку. Именно с такой ситуацией и столкнулся Мефодий.
- зависимость пакетов
- Ситуация, при которой пакет не может быть установлен в систему, если в ней не установлен хотя бы один из некоторого множества пакетов. Аналогично, пакет не может быть удалён из системы до тех пор, пока в ней установлен хотя бы один зависящий от него пакет.
Библиотеки
Мефодию помешала установить пакет самая типичная зависимость — на библиотеку. Библиотеки возникают оттого, что все программы, сколько бы они не отличались друг от друга, нуждаются в выполнении одних и тех же операций: вводе и выводе, получении доступа к ресурсам системы (памяти, процессорному времени, файлам), вычислениях, работе с сетью, рисовании окошек, кнопок, меню и т. п. Для выполнения таких операций используются небольшие подпрограммы — функции. Любые функции, необходимые более чем одной программе, есть смысл не включать в текст каждой программы, а собирать в отдельных библиотеках. Тогда программа сможет использовать не собственную подпрограмму, а готовую функцию из библиотеки. Поскольку библиотеки нужны нескольким программам, они обычно оформляются в виде отдельного пакета. Если библиотека не будет установлена, использующая её программа просто не будет работать.
Библиотеки подвержены тем же изменениям с течением времени, что и все прочие программы: исправлению обнаруженных ошибок, модернизации, оптимизации и пр. Поэтому версии библиотек должны быть согласованы с версией программного обеспечения. Например, программа может отказаться работать даже при наличии библиотеки, если эта библиотека слишком старая либо слишком новая по сравнению с самой программой.
Цепочки зависимостей
Однако понятие зависимости включает не только зависимость программы от библиотек. Вообще говоря, зависимость возникает там, где программное обеспечение использует любой не поставляемый непосредственно с ним ресурс.
Имеет смысл исключать из понятия зависимости использование наиболее стандартных ресурсов, без которых немыслима система Linux как таковая. К таким ресурсам можно отнести системные вызовы и некоторые стандартные файлы, вроде /dev/null
.
Это могут быть и утилиты, которые запускаются при работе самой программы или во включённых в пакет сценариях, программа-интерпретатор для исполнения этих сценариев, и даже определённые файлы, которые должны присутствовать для правильной работы программы (например, утилита passwd
предполагает, что существует файл /etc/passwd
).
Зависимость может быть и небезусловной. Например, в некоторых случаях нужно обеспечить наличие ресурса не к моменту запуска программы, а прямо к моменту установки пакета, так, для выполнения доустановочного сценария нужна программа-интерпретатор. В некоторых случаях требуется ресурс строго определённой версии, ни больше, ни меньше. Бывают случаи, когда зависимость имеет обобщённую форму, например, почтовому клиенту (программе для чтения и написания электронной почты) может требоваться служба доставки электронной почты. В Linux такую услугу предоставляют несколько разных программ, и любая из них удовлетворит зависимость.
Разобравшись с понятием зависимости, Мефодий набрался твёрдой решимости установить-таки нужный ему пакет, установив всё, что он потребует. Но не тут-то было: взявшись устанавливать библиотеки, Мефодий выяснил, что каждой из них требуются какие-то ещё пакеты, отсутствующие в системе, у каждого из них тоже есть зависимости и т. п. — один единственный пакет повлёк за собой снежный ком других, вытягивая их по цепочкам зависимостей.
Конфликты и альтернативы
В противоположность зависимости, когда пакет не может быть установлен при отсутствии некоторого другого, конфликт пакетов — это ситуация, когда пакет не может быть установлен при наличии некоторого другого, т. е. они несовместимы в рамках одной системы. Одна из причин возникновения конфликтов уже упоминалась выше — в пакетах есть файлы с совпадающими именами. Самый распростанённый источник конфликтов — программы, которые предоставляют разные реализации одной и той же функциональности системы (например, службы доставки электронной почты или печати, программы проверки орфографии, компиляторы и т. п.). Можно было бы, конечно, просто назвать конфликтующие файлы по-разному, но и тогда путаница неизбежна: если, допустим, старый компилятор Си называется gcc2.96
, а новый — gcc3.3
, то что запускается по стандартной команде gcc
? В каждом пакете должна содержаться информация о том, с какими пакетами он конфликтует. Конфликт пакетов может быть разрешён очень просто: следует удалить один из конфликтных пакетов, после чего свободно устанавливать другой.
Каждый пакет помимо имени обозначен и номером версии, указывающим степень обновлённости содержащегося в пакете программного обеспечения и самого пакета. В системе одновременно может быть установлена только одна версия любого пакета, со всеми остальными версиями она конфликтует. Такой подход вполне понятен, поскольку файлы в пакете имеют строго определённый путь, по которому они должны быть размещены в файловой системе. Поэтому при использовании пакетов не должно (и не может) возникнуть ситуации, когда одна и та же программа установлена в разных местах файловой системы.
Однако не все функции в системе должны эксклюзивно выполняться одной программой. Например, в системе может быть установлено сколько угодно текстовых редакторов, и даже несколько разных реализаций одного редактора, например, Vim (Vi и nvi). Пакеты Vi и nvi не конфликтуют друг с другом, однако оба могут с равным правом быть вызваны по команде vi
. Чтобы определить, какой именно из них запускать как vi
, во многих дистрибутивах Linux (в частности, в том, который использует Мефодий) используется механизм альтернатив. Альтернативы — это система символьных ссылок на принадлежащие пакетам файлы. Однотипные файлы из пакетов называются по-разному, а символьная ссылка, к которой обращается пользватель, указывает на один из них. Например, файл /usr/bin/vi
может быть символьной ссылкой либо на /usr/bin/vim
, либо на /usr/bin/nvi (то же самое относится и к руководствам по этим редакторам). При установке и удалении любого из пакетов с одной из альтернативных программ символьная ссылка автоматически обновляется. На какую из них будет указывать ссылка решается на основании веса каждого пакета. Вес — это условное число, выбирается та альтернатива из установленных, у которой наибольший вес. Пользователь может вмешаться в выбор альтернатив и вручную. Все необходимые утилиты для работы с альтернативами предоставляет пакет alternatives
.