Но вот в чём главная трудность: "aptitude install" устанавливает пакеты
с их зависимостями (также рекомендуемыми и предлагаемыми пакетами (в зависимости от настроек пользователя)). Поэтому необходимо проверять на "несистемность" и наличие в нужном дистрибутиве не только сами пакеты (параметры командной строки), но и всё дерево их зависимостей, которые aptitude захочет установить! Например, пакет
phpbb3 - несистемный (с точки зрения моей функции IsPackageDangerous()), но он зависит от пакета
dbconfig-common, который имеет таги admin::configuring и admin::package-management.
Первая идея, которая пришла мне в голову заключается в том, что нужно
рекурсивно (используя output комманды "apt-cache depends") проверять на несистемность все
неустановленные зависимости. Тогда, конечно, необходимо проверять всё дерево зависимостей и
на конфликты: конфликтует ли пакет с каким-нибудь уже установленным. Разумеется, такие конфликты допускать нельзя, иначе пользователь сможет деинсталлировать некоторые пакеты.
Но здесь есть подводные камни, и этот метод правильно работать не будет! Во первых, среди пакетов пользователя (или из зависимостей) могут быть
виртуальные, которые "aptitude install"' может заменить на реальные, но ... их зависимости нельзя узнать. Во вторых, мы не знаем будет ли "aptitude install" автоматически ставить рекомендуемые и предлагаемые пакеты (это зависит от насктроек). В третьих, некоторые пакеты aptitudом могут быть брошены или downgraded.
Из-за этого я отбросил первую идею и решить полностью положиться на output команды "aptitude install". Её нужно
заранее запускать с опциями
--simulate (чтобы она не начала инсталлировать, пока скрипт ещё ничего не проверил) и
--assume-yes (чтобы не задавала вопросов).
Сторока за строкой я читаю вывод комманды
aptitude $INSTALLEROPTIONS --simulate --assume-yes install $ALLPARAMS и ищю, где начинается и где кончается список пакетов для инсталляции, проверяя сообщения команды "aptitudе install". Для этого мне даже пришлось составить список сообщений:
INSTALLEDPRELIMINARYSTR="The following NEW packages will be installed:"
REMOVEDPRELIMINARYSTR="The following packages will be REMOVED:"
BROKENPRELIMINARYSTR="The following packages are BROKEN:"
UPGRADEDPRELIMINARYSTR="The following packages will be upgraded:"
DOWNGRADEDPRELIMINARYSTR="The following packages will be DOWNGRADED:"
Найденные строки с пакетами для установки нужно парсить и удалять из них флаги (типа
{a}), после чего проверять их на "несистемность" и наличие в нужном дистрибутиве. Удобно то, что "aptitude install" сам составит полное дерево зависимостей так, как ему угодно, и выведет его в стандартный поток вывода. Тут же можно и проверить, собирается ли "aptitude install" что-либо деисталлировать, бросать или даунгрэйдить (из-за конфликтов). Читайте код функции
CheckSafetyOfAllInstalledPackages() в моём скрипте (ссылка выше).
Я прекрасно понимаю, что моя реализации жутко кривая

. Конечно, нельзя полагать на output, который предназначен только для удобства пользователя и его формат может быть изменён. Код функции выглядит даже как-то маразматически.