Установите несколько файлов deb, уважая их зависимости
Для поддержки автономной установки нескольких .deb
файлы, которые я использую:
sudo dpkg -i dependencies/*.deb
Я заметил, что некоторые пакеты не могут использовать этот метод из-за порядка их установки
Например, это то, что происходит при установке mariadb-server-5.5
и его зависимости:
Как я могу установить *.deb
файлы при уважении их зависимостей?
- Я пытаюсь избежать создания локального репо, так как его сложнее поддерживать.
- В качестве обходного пути я запускаю команду
dpkg -i *.deb
дважды.
3 ответа
Топологическая сортировка (через скрипт)
Команда dpkg -i packages/*.deb
проблематично - не соблюдает должным образом порядок установки пакетов (даже если вы поставите все необходимые пакеты).
Пользовательский скрипт для управления ими всеми
Предполагается, что в вашем дистрибутиве Debian установлен Python (у меня Ubuntu 14.04 LTS и поставляется с
python27
)
Помимо оффлайн.deb packages
каталог, предоставьте скрипт, который;
- Извлечение метаданных и топологическая сортировка всех пакетов-кандидатов
- Пользы
dpkg -i
установить отсортированные пакеты в правильном порядке, они должны быть установлены
Например, выполните эту команду, чтобы установить все предварительно собранные автономные пакеты
sudo python install.py
install.py
#!/usr/bin/env python
import os
import re
import subprocess
import logging
import sys
rootLogger = logging.getLogger()
rootLogger.setLevel(logging.INFO)
consoleHandler = logging.StreamHandler(sys.stdout)
consoleHandler.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(message)s"))
rootLogger.addHandler(consoleHandler)
SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
class TopologicalSort(object):
def __init__(self, dependency_map):
self._dependency_map = dependency_map
self._already_processed = set()
def _get_dependencies(self, item, root=None):
if not root:
root = item
elif root == item:
logging.warn("circular dependency detected in '{}'".format(item))
raise StopIteration()
dependencies = self._dependency_map.get(item, [])
for dependency in dependencies:
if dependency in self._already_processed:
continue
self._already_processed.add(dependency)
for sub_dependency in self._get_dependencies(dependency, root=root):
yield sub_dependency
yield dependency
def sort(self):
# Reduction, connect all nodes to a dummy node and re-calculate
special_package_id = 'topological-sort-special-node'
self._dependency_map[special_package_id] = self._dependency_map.keys()
sorted_dependencies = self._get_dependencies(special_package_id)
sorted_dependencies = list(sorted_dependencies)
del self._dependency_map[special_package_id]
# Remove "noise" dependencies (only referenced, not declared)
sorted_dependencies = filter(lambda x: x in self._dependency_map, sorted_dependencies)
return sorted_dependencies
class DebianPackage(object):
def __init__(self, file_path):
metadata = subprocess.check_output('dpkg -I {}'.format(file_path), shell=True)
metadata = metadata.replace('\n ', '\n')
self._metadata = metadata
self.id = self._get('Package')
self.dependencies = list(self._get_dependencies())
self.file_path = file_path
def _get_dependencies(self):
dependencies = self._get('Depends') + ',' + self._get('Pre-Depends')
dependencies = re.split(r',|\|', dependencies)
dependencies = map(lambda x: re.sub(r'\(.*\)|:any', '', x).strip(), dependencies)
dependencies = filter(lambda x: x, dependencies)
dependencies = set(dependencies)
for dependency in dependencies:
yield dependency
def _get(self, key):
search = re.search(r'\n{key}:(.*)\n[A-Z]'.format(key=key), self._metadata)
return search.group(1).strip() if search else ''
def sort_debian_packages(directory_path):
file_names = os.listdir(directory_path)
debian_packages = {}
dependency_map = {}
for file_name in file_names:
file_path = os.path.join(directory_path, file_name)
if not os.path.isfile(file_path):
continue
debian_package = DebianPackage(file_path)
debian_packages[debian_package.id] = debian_package
dependency_map[debian_package.id] = debian_package.dependencies
sorted_dependencies = TopologicalSort(dependency_map).sort()
sorted_dependencies = map(lambda package_id: debian_packages[package_id].file_path, sorted_dependencies)
return sorted_dependencies
def main():
# ------------------
# Sort the packages using topological sort
packages_dir_path = os.path.join(SCRIPT_DIR, 'packages')
logging.info('sorting packages in "{}" using topological sort ...'.format(packages_dir_path))
sorted_packages = sort_debian_packages(packages_dir_path)
# ------------------
# Install the packages in the sorted order
for index, package_file_path in enumerate(sorted_packages):
command = 'dpkg -i {}'.format(package_file_path)
logging.info('executing "{}" ...'.format(command))
subprocess.check_call(command, shell=True)
if __name__ == '__main__':
if os.geteuid() != 0:
logging.error('must be run as root')
sys.exit(1)
try:
main()
except:
logging.error('failed to install packages', exc_info=True)
sys.exit(1)
Вы можете попробовать с -R и установить опции:
sudo dpkg -R --install dependencies/
-R Рекурсивно обрабатывать все обычные файлы, соответствующие шаблону *.deb, найденному в определенных каталогах и во всех его подкаталогах.
Я не эксперт по dpkg, но это
--force-depends
флаг вроде работает.
Я бы сначала убедился, что все зависимости выполнены, используя
dkpg-deb -I <package.deb>
или еще лучше, рекурсивно для каждого
.deb
у вас есть в текущей папке:
ls -1 -d "$PWD"/* | xargs --max-lines=1 dpkg-deb -I | grep --only-matching --perl-regexp "(?<=Depends: ).*" | sed -z 's/, /\n/g' | sort | uniq -u
Если все эти зависимости содержатся в pwd или уже установлены в системе, то просто установите все
.debs
в pwd с:
dpkg --force-depends -i ./*
Чтобы узнать больше о принудительном флаге:
man dpkg --force-help