Linux Desktop — почему всё так плохо? Стандарт FHS и управление ПО
05.07.2024
В данной части статьи хотелось бы рассмотреть ещё одну проблему, связанную с расположением системных файлов в ОС, а также ряд характерных особенностей именно дистрибутивов GNU/Linux по сравнению с другими UNIX-системами, которые следуют тому же самому стандарту файловой системы, что и Linux.
Речь идёт про стандарт FHS. Он указывает разработчикам операционных систем семейства UNIX, какие файлы в каких местах должны быть расположены. Соответственно содержимое всех этих /bin
, /etc
, /srv
, /usr
и т.д. У данного стандарта есть как свои плюсы, так и свои минусы, но иногда для конечного пользователя минусов оказывается всё-таки больше.
Данный стандарт хорош тем, что системные файлы находятся в предсказуемых местах и их легко при необходимости найти. Ну и то, что этот стандарт распространён не только среди дистрибутивов GNU/Linux, для которых он и был принят, а для многих систем семейства UNIX вообще, а это значит, что расположение файлов в программе для разных ОС не придётся изменять. Это повышает переносимость ПО.
Однако у FHS есть и ряд минусов. Условно я подразделяю всё программное обеспечение на 3 типа:
- Системное ПО, предназначенное для работы ОС (
linux
,coreutils
,util-linux
,bash
,glibc
, etc.). В хороших продуманных системах такое ПО не должно подлежать удалению и, по хорошему, должно быть отделено от всего остального ПО. - ПО, тесно связанное с ОС, но устанавливаемое, как правило, пользователем. Обычно используется для обеспечения работоспособности другого ПО (например, среды запуска или интерпретаторы скриптовых языков программирования), либо предназначено для разработки (IDE, компиляторы, отладчики) или для системного администрирования (серверы, средства виртуализации).
- Пользовательское ПО — всякие браузеры, офисные пакеты, игры, т.е. всё то ПО, с которым взаимодействует только пользователь (причём неважно что это за пользователь). Как правило, в современных ОС такое ПО графическое (в отличие от первых двух типов, где подавляющее число программ консольное).
В современных дистрибутивах Linux все эти три типа ПО находятся в одной куче. У нас есть каталоги /usr/bin
1 и /usr/sbin
2, в которых хранятся сами программы, у нас есть /usr/lib
, где хранятся библиотеки и /etc
с конфигурационными файлами. В случае ошибок, например, при обновлении какой-то пользовательской программы, есть вероятность того, что произойдёт сбой ещё и в какой-то системной программе. Радует то, что такая проблема характерна обычно для GNU/Linux, в которой каталоги /{bin,sbin,lib}
с системным софтом заменены на ссылки на их аналоги в /usr
, а вот в системах семейства BSD такой проблемы нет, так как всё ПО, которое устанавливает пользователь, содержится в /usr/local/...
, что, однозначно, плюс. Да, для такой “раздельной” структуры каталогов, где папки с “системным” ПО находятся отдельно от папки с “пользовательским”, куда сложнее собирать ПО. Да и стандарт FHS в таком случае требует, чтобы в /{bin,sbin,lib}
содержались строго определённые программы и библиотеки, т.е. нужно ещё и проверять, всё ли у нас на месте, а в случае с “совмещённой”, которую используют в данный момент многие дистрибутивы GNU/Linux, всё гораздо проще, но тогда будет страдать надёжность системы.
Кроме того, использование FHS вкупе с повальной модой на внешние зависимости, когда программа использует в своей работе другие программы и библиотеки, так же присутствующие в системе, высока вероятность возникновения конфликтов и т.н. dependency hell, когда несколько пакетов имеют одну и ту же зависимость, но разных версий. Использование стандарта FHS подразумевает наличие в системе только одной версии пакета. Конечно, мы можем установить другую версию пакета с программой в другое место (есть же всякие /opt
и /usr/local
), но можем ли мы гарантировать, что эти пакеты будут нормально функционировать? А будет ли корректно функционировать ПО, зависящее от этих пакетов? К примеру, можем ли мы гарантировать, что программа A
будет использовать библиотеку libsome
версии 1.0, которая установлена в /usr/lib
, а не библиотеку libsome
версии 2.3, которая установлена уже в /usr/local
?
Подводя итог: FHS не предполагает наличия в системе более одной версии программы. Обычно пользователю на это наплевать, но данное “ограничение” может спровоцировать dependency hell. Кроме того, то, что делают современные дистрибутивы GNU/Linux, по словам их разработчиков, для упрощения, может быть что-то и упрощает (сборка ПО под “упрощённую” структуру файловой системы действительно упрощает сборку ПО, в особенности системного), но больше вредит, поскольку всё ПО теперь находится буквально в одной куче. Кроме того, поскольку всё ПО и так находится “в куче”, могут возникать конфликты пакетов, когда несколько таковых устанавливают в систему файлы по одному и тому же пути. К примеру, пакет pkg1
устанавливает в систему библиотеку libsome
(/usr/lib/libsome
), и пакет pkg2
устанавливает библиотеку с тем же именем в тот же путь /usr/lib/libsome
. Такое поведение недопустимо и хороший пакетный менеджер, устанавливающий эти пакеты, должен прервать установку. Если он этого не сделает, то возможны сбои в тех программах, которые используют эту самую libsome
в своей работе.
Однако то, что ПО находится “в куче”, можно посчитать и плюсом. Такое расположение программ как нельзя кстати подходит для системного ПО. Всякие coreutils
, util-linux
, shadow
, etc. будут как одно целое и это хорошо. Однако для остального ПО, которое, как правило, устанавливает в систему пользователь, такая структура уже не подойдёт. Что же делать?
Я считаю, что всякое консольное ПО или библиотеки, предназначенные для разработчиков, либо же тесно связанные с ОС, но не являющиеся её частью, нужно устанавливать в /usr/local
. Там так же, как и в остальной системе (/
, /usr
) есть каталоги {bin,sbin,lib}
, как в /usr
там есть каталог share
, поэтому ничто не мешает устанавливать такое ПО туда. Да, оно по-прежнему будет в одной куче, но эта куча будет отдельно от основной системы, что может несколько повысить безопасность и надёжность последней.
А вот всё ПО, которое предназначено для пользователя и этим пользователем оно устанавливается в систему (браузеры, офисные пакеты, игры, etc.), нужно устанавливать уже в другое место и так, чтобы это ПО было изолировано друг от друга и не имело друг с другом ничего общего кроме ОС, на которой оно работает. Под словом “изолировано” я не понимаю контейнеризацию вроде тех же пакетов формата flatpak или snap, поскольку это медленнее и в некоторых случаях ресурсозатратнее (такое ПО хранится в отдельных образах, которые куда-то там монтируются, которые работают медленно и неохотно). Под этим словом я понимаю, что каждый пакет изолирован друг от друга в файловой системе и не пересекается друг с другом. К примеру, пакет firefox
установлен в /apps/firefox.app
, в которой хранится его *.desktop-файл
, логотип, информация о пакете (версия, разработчик и т.д.), все необходимые зависимости нужных версий и сам Firefox, пакет libreoffice
установлен в /apps/libreoffice.app
, в которой так же хранятся *.desktop
, логотип, зависимости и файлы самогО пакета.
Подобный вариант (нагло скопированный мною из macOS и слегка видоизменённый для GNU/Linux) быстрее, чем snap и flatpak, потому что ничего не запускается ни в каких песочницах или иных изолированных от ОС пространств. В macOS такие папки с пакетами в файловом менеджере Finder отображаются не как папки, а как файлы определённого типа, имеющие название, иконку (в качестве иконки - логотип программы), версию и т.д. Нужно “открыть” такой “файл” и у нас запустится программа оттуда.
И в главном меню системы такие папки отображаются не как папки, а как иконки приложений. Нажал на иконку в меню - запустил программу.
Для установки такой программы нужно скопировать папку с ней в /apps
, а для удаления - удалить эту папку из /apps
. Подобное решение позволит снизить частоту обращения к пакетным менеджерам, сведя их обязанности только к установке обновлений системы и установке/удалении/обновлении каких-то утилит, установленных в /usr/local
.
-
В современных дистрибутивах GNU/Linux
/bin
,/sbin
и/lib
, содержащие только системные программы и библиотеки, доступные как в много-, так и в однопользовательском режимах, теперь не каталоги, а ссылки на их аналоги в/usr
. ↩ -
Уже идёт речь об отказе от «обычного» каталога
/usr/sbin
в пользу ссылки/usr/sbin
->/usr/bin
. Т.е. возможно, что в будущем у нас абсолютно всё ПО будет содержаться в ещё бОльшей куче в/usr/bin
— и только в нём! ↩