Любой, кто хоть раз ставил софт в Linux, набирал либо apt install, либо pacman ‑S. Внешне разница выглядит косметической: одна утилита требует длинных слов, другая — коротких флагов. На самом деле за этими командами стоят две принципиально разные инженерные философии, и почти каждое различие между ними — не каприз разработчиков, а прямое следствие того, как устроен сам дистрибутив.
В этой статье разберём, что происходит внутри при установке пакета, как устроены форматы, базы данных и разрешение зависимостей, и почему pacman заметно быстрее, но при этом опаснее в руках новичка.
Два уровня вместо одного
Первое, что стоит уяснить: apt — это не программа установки пакетов. Это программа, которая решает, что установить, скачивает файлы и отдаёт их другой программе.
В экосистеме Debian есть чёткое разделение:
dpkg — низкоуровневый инструмент. Умеет распаковать один конкретный.deb‑файл, прописать его в базу и запустить служебные скрипты. О репозиториях и зависимостях он не знает почти ничего: если пакету что‑то не хватает, dpkg просто откажется его настраивать.
apt / apt‑get / aptitude — высокоуровневые фронтенды (интерфейсы). Они читают метаданные репозиториев, вычисляют полный набор пакетов, качают их и вызывают dpkg.
libapt‑pkg — общая библиотека, где живёт вся реальная логика: кэш пакетов, решатель зависимостей, система загрузки. apt и apt‑get — это тонкие обёртки над ней.
У Arch структура такая же двухслойная, просто менее заметная:
libalpm (Arch Linux Package Management library) — движок. Именно он работает с базами, проверяет конфликты, выполняет транзакции.
pacman — консольный фронтенд к libalpm.
Отсюда, кстати, растут все «альтернативные пакетные менеджеры» Arch: pamac, yay, paru — это надстройки, а не замены.
Практический вывод: dpkg ‑i пакет.deb и pacman ‑U пакет.pkg.tar.zst — операции одного уровня (поставить локальный файл), а apt install и pacman ‑S — другого (найти в репозитории, разрешить зависимости, поставить).
Формат пакета: архив внутри архива против обычного тарбола
deb — это архив формата ar (древний Unix‑архиватор, предшественник tar), внутри которого строго три элемента в определённом порядке:
debian‑binary — текстовый файл с версией формата («2.0»)
control.tar.xz — метаданные и скрипты
data.tar.xz — собственно файлы, которые лягут в файловую систему
Разобрать руками можно за две команды:
ar x пакет.deb
tar tf control.tar.xz
Внутри control.tar лежат: control (имя, версия, архитектура, зависимости, описание), md5sums (контрольные суммы установленных файлов), conffiles (список конфигов), скрипты preinst, postinst, prerm, postrm, и опционально triggers и templates (шаблоны вопросов для debconf — системы интерактивной настройки пакетов).
pkg.tar.zst — это просто tar‑архив, сжатый zstd. Никакой вложенности. Метаданные лежат рядом с файлами в виде точечных файлов:
PKGINFO — метаданные в формате ключ = значение. Зависимости, конфликты, размеры.
MTREE — сжатый список всех файлов пакета с хешами, правами доступа, владельцем и временными метками. Это богаче, чем md5sums у Debian, где хранятся только контрольные суммы содержимого. Благодаря.MTREE работает pacman ‑Qk — проверка целостности установленного.
BUILDINFO — данные для воспроизводимой сборки (reproducible builds — возможность независимо пересобрать пакет байт‑в-байт и убедиться, что он собран из заявленных исходников).
INSTALL — необязательный файл со скриптами. Ключевое слово — необязательный: у большинства пакетов Arch его просто нет.
Вот это последнее различие — самое важное во всей статье, и к нему мы вернёмся.
База данных установленного
dpkg хранит состояние в одном большом текстовом файле /var/lib/dpkg/status. Формат — RFC822-подобные блоки (те же «поле: значение», что в заголовках почты), разделённые пустой строкой. Рядом лежит каталог /var/lib/dpkg/info/ со списками файлов (пакет.list), контрольными суммами и самими скриптами сопровождающего.
У dpkg есть полноценный конечный автомат состояний пакета: not‑installed, unpacked (файлы распакованы, но настройка не выполнена), half‑configured, half‑installed, config‑files (пакет удалён, но конфиги оставлены), installed. Именно поэтому Debian переживает прерванное обновление: система помнит, кто на каком шаге застрял, и dpkg ‑configure ‑a доводит дело до конца.
pacman идёт противоположным путём — вместо одной большой базы у него куча мелких текстовых файлов:
/var/lib/pacman/local/имя‑пакета‑версия/
desc — метаданные
files — список файлов и mtree‑данные
Синхронизированные базы репозиториев — это /var/lib/pacman/sync/core.db, extra.db и так далее, каждая из которых представляет собой сжатый тарбол с теми же desc‑файлами. Обновляются командой pacman ‑Sy.
Плюс подхода в том, что «повредиться» тут почти нечему: это обычные файлы, их можно прочитать cat‑ом и при необходимости починить руками. Минус — он же: отсутствие атомарности на уровне файловой системы. Если питание отключится во время записи, текстовые файлы могут повредиться (в отличие от бинарных БД, использующих WAL‑журналы).
Метаданные репозиториев и модели доверия
Здесь различие принципиальное, и оно касается безопасности.
Debian подписывает репозиторий. В каталоге dists/<выпуск>/ лежит файл InRelease с встроенной OpenPGP‑подписью, содержащий хеши всех индексных файлов Packages. Те, в свою очередь, содержат хеши всех.deb. Получается цепочка доверия: доверяем ключу архива → доверяем InRelease → доверяем индексу → доверяем конкретному пакету. Сами.deb‑файлы не подписаны.
Отдельно стоит упомянуть механизм by‑hash: индексы можно скачивать по URL, содержащему их собственный хеш. Это избавляет от классической ошибки «Hash Sum Mismatch», когда зеркало обновилось прямо посреди вашей загрузки.
Управление ключами за последние годы изменилось. Старый apt‑key добавлял ключи в единое глобальное хранилище, и любой такой ключ мог подписывать что угодно от имени любого репозитория — очевидная дыра. Сейчас правильный способ — класть ключ в /etc/apt/keyrings/ и указывать его для конкретного источника через Signed‑By:. В Debian 13 “Trixie” apt‑key уже удалён.
Источники, кстати, тоже мигрируют: одностроковый /etc/apt/sources.list считается устаревшим, на смену пришёл формат deb822 — многострочные блоки в /etc/apt/sources.list.d/*.sources:
Types: deb
URIs: https://deb.debian.org/debian
Suites: trixie
Components: main contrib non‑free
Signed‑By: /etc/apt/keyrings/debian‑archive.gpg
Arch подписывает каждый пакет и базы репозиториев. Проверка идёт через сеть доверия (web of trust): при установке системы создаётся локальный корневой ключ, который подписывает мастер‑ключи Arch, а те подписывают ключи всех разработчиков и мейнтейнеров пакетов (они приезжают в пакете archlinux‑keyring). Управляет этим pacman‑key, хранилище — /etc/pacman.d/gnupg/.
Отсюда самая частая ошибка новичка в Arch: “invalid or corrupted package (PGP signature)” после долгого перерыва в обновлениях. Пакет не сломан — просто ваш keyring устарел и не знает ключа, которым он подписан. Лечится обновлением archlinux‑keyring перед основным обновлением.
Зависимости: богатый словарь против минимализма
Debian Policy определяет впечатляющий набор типов связей между пакетами:
Поле | Смысл |
Depends | жёсткая зависимость |
Pre‑Depends | должна быть полностью настроена до начала распаковки текущего пакета |
Recommends | «почти зависимость» — ставится по умолчанию, но может быть отключена |
Suggests | рекомендация, автоматически не ставится |
Enhances | обратный Suggests: пакет заявляет, что расширяет другой |
Breaks | ломает указанный пакет указанной версии |
Conflicts | не может быть установлен совместно |
Replaces | забирает себе файлы другого пакета |
Provides | предоставляет виртуальный пакет (например, десяток почтовых серверов предоставляет mail‑transport‑agent) |
Плюс версионные ограничения (foo (>= 1.2)) и альтернативы (a | b). Отдельная история — multi‑arch: возможность держать в системе библиотеки нескольких архитектур сразу (amd64 и i386), что порождает поля Multi‑Arch: same/foreign/allowed и заметно усложняет работу решателя.
У pacman словарь короче: depends, makedepends (нужны только при сборке), optdepends, provides, conflicts, replaces. Ключевой момент: optdepends ничего не устанавливает. Это буквально текстовая подсказка пользователю: «для поддержки такого‑то формата поставьте вот этот пакет». Аналога Recommends с автоматической установкой в Arch нет вообще.
Решатель зависимостей
Разрешение зависимостей в общем случае — NP‑полная задача (класс задач, для которых не известно быстрого алгоритма решения). APT исторически использовал эвристический алгоритм: быстрый, но иногда сдававшийся или предлагавший неожиданно снести пол‑системы.
В APT есть протокол EDSP (External Dependency Solver Protocol), позволяющий делегировать разрешение внешнему решателю — например, aspcud через прослойку apt‑cudf. Такие решатели гарантированно находят решение, если оно существует, но работают медленнее.
Важное изменение последних лет — переход на solver3 (релиз в APT 3.0, апрель 2025). Это уже настоящий алгоритм с возвратом (backtracking): он начинает с пустого множества, фиксирует вручную установленные пакеты как неизменяемые факты, добавляет зависимости, у которых есть единственное решение, а неоднозначные (a | b | c) откладывает в очередь с приоритетом, разбирая сначала те, где вариантов меньше. При конфликте откатывается на уровень назад и пробует иначе. Автор, Julian Andres Klode, описывает это как DPLL‑решатель (классический алгоритм для задачи выполнимости булевых формул) без исключения чистых литералов.
Практические следствия: solver3 избегает удаления вручную установленных пакетов (помечает их как жесткие ограничения), зато агрессивнее чистит автоматические, и строит граф импликаций, на котором основана команда apt why.
Важное уточнение, потому что в популярных статьях это часто путают: в Debian 13 “Trixie” (APT 3.0.3) solver3 поставляется, но не включён по умолчанию — классический решатель остаётся основным, а новый доступен через ‑solver 3.0. По умолчанию solver3 стал включаться начиная с серии APT 3.1 (то есть в testing/unstable) и в Ubuntu 26.04. На момент написания статьи APT развивается до версии 3.2.0, где появляется функциональность отката операций.
APT 3.0 также заметно изменил внешний вид: цветной вывод (красный — удаления, зелёный — остальное), колоночная вёрстка списка пакетов и внятные сообщения об ошибках зависимостей. Плюс переход на проверку подписей через sqv от проекта Sequoia PGP — верификатор, написанный на Rust, то есть на языке с безопасной работой с памятью.
Решатель pacman намеренно проще и никакого бэктрекинга не использует. И он может себе это позволить — по причине, о которой ниже.
Скрипты сопровождающего против хуков
Вот здесь проходит главный водораздел.
Debian: почти каждый пакет несёт свои скрипты, и dpkg исполняет их в строго определённом порядке. При обновлении сценарий выглядит так:
old‑prerm upgrade <новая‑версия>
→ распаковка новых файлов поверх старых
old‑postrm upgrade <новая‑версия>
new‑postinst configure <старая‑версия>
Если что‑то падает, dpkg вызывает обратные варианты (abort‑upgrade, failed‑upgrade), поэтому Debian Policy требует, чтобы скрипты были идемпотентны (повторный запуск не должен менять результат). Через эти скрипты создаются системные пользователи, запускаются и останавливаются службы, регистрируются альтернативы.
Чтобы не выполнять дорогие операции по сто раз за обновление, dpkg имеет триггеры: пакет может отложить действие (ldconfig, перестроение индекса man‑страниц, пересборка initramfs), и оно выполнится один раз в конце пакетной операции.
Arch: у большинства пакетов скриптов нет вовсе. Системные действия вынесены в хуки libalpm — файлы *.hook в /usr/share/libalpm/hooks/ (системные) и /etc/pacman.d/hooks/ (администраторские):
[Trigger]
Operation = Install
Operation = Upgrade
Type = Path
Target = usr/lib/modules/*/vmlinuz
[Action]
Description = Перестроение initramfs...
When = PostTransaction
Exec = /usr/bin/mkinitcpio ‑P
Логика инвертирована: не пакет говорит «после моей установки сделай X», а система говорит «если в транзакции затронуты такие‑то файлы — выполни X один раз». Хуки бывают PreTransaction и PostTransaction; последние не выполняются, если транзакция провалилась.
Это архитектурно чище и — что важнее для ощущений пользователя — существенно быстрее.
Конфигурационные файлы: спросить или не мешать
Оба менеджера решают одну задачу: пакет обновился, конфиг в новой версии изменился, но пользователь тоже правил его руками. Слить автоматически нельзя. Решения диаметрально противоположные.
dpkg сравнивает три версии файла (исходную, текущую на диске и новую) и, если пользователь файл менял, останавливает установку и задаёт вопрос: поставить версию мейнтейнера, оставить свою, показать diff или запустить шелл. Стандартные конфиги обрабатывает сам dpkg. А пакеты со сложной логикой конфигурации (например, почтовые серверы) используют вспомогательную утилиту ucf.
pacman в той же ситуации не спрашивает ничего. Ваш файл остаётся нетронутым, новая версия кладётся рядом как конфиг.pacnew, в лог падает предупреждение, транзакция идёт дальше. При удалении пакета изменённый конфиг сохраняется как.pacsave. Средств автоматического слияния pacman не предоставляет — разбираетесь вы, руками или утилитой pacdiff.
Это и есть та самая разница философий в чистом виде: Debian считает, что дистрибутив отвечает за корректную интеграцию и потому имеет право прервать вас вопросом; Arch считает, что за конфигурацию отвечает пользователь, и потому никогда не блокирует процесс, но и не убирает за вами.
Частичные обновления — главная ловушка Arch
Если из статьи вы запомните один абзац, пусть это будет этот.
Arch — rolling‑релиз без ABI‑стабильности (ABI, Application Binary Interface — двоичный интерфейс: то, как скомпилированная программа обращается к библиотеке). Старые версии библиотек в репозитории не хранятся. Отсюда следует, что состояние системы должно быть целостным на один момент времени.
Команда pacman ‑Sy обновляет базу репозиториев, но не пакеты. Если после неё выполнить pacman ‑S какой‑нибудь‑пакет, то новый пакет притянет свежую версию, скажем, libfoo.so.3, тогда как половина системы всё ещё слинкована с libfoo.so.2, которого в репозитории уже нет. Получается частичное обновление (partial upgrade) — состояние, которое Arch официально не поддерживает и которое ломает систему вплоть до неработающего pacman.
Правило: единственная безопасная команда обновления — pacman ‑Syu. Не ‑Sy, не ‑Sy пакет, не ‑Syuw (только скачать) с последующей установкой позже.
В Debian такой опасности нет: внутри релиза старые версии библиотек остаются доступны, пакеты явно объявляют версионные зависимости, и apt install спокойно доставит нужную. Именно поэтому pacman может позволить себе примитивный решатель — за него работу делает жёсткое ограничение «система всегда полностью актуальна».
Скорость: почему pacman ощутимо быстрее
Разница реальна, и она структурная, а не случайная:
1. Простая база. Мелкие текстовые файлы и тарболы читаются быстро; APT парсит и держит в памяти большой кэш со сложной моделью зависимостей и multi‑arch.
2. Простой решатель. Отсутствие бэктрекинга и мягких зависимостей резко сокращает пространство поиска.
3. zstd. Arch использует zstd для всего пакета и для баз репозиториев (sync.db). Debian тоже перешел на zstd для payload в.deb, но pacman выигрывает за счет того, что весь архив целиком и метаданные сжаты одним потоком zstd, что дает прирост к скорости парсинга баз.
4. Отсутствие скриптов. Это главное. Обновление сотни пакетов в Debian означает запуск сотен shell‑скриптов плюс обработку триггеров. В Arch — распаковку архивов и несколько хуков в конце.
Сразу оговорюсь: воспроизводимых бенчмарков «apt против pacman» на одинаковом железе почти нет, и любые цифры сильно зависят от зеркала, диска и набора пакетов. Правильнее говорить не «pacman быстрее на N%», а «pacman быстрее по устройству, и вот по каким четырём причинам».
Кстати, о трафике: Debian использует pdiff — инкрементальные диффы индексных файлов, чтобы apt update качал только изменения метаданных. У Arch когда‑то были дельта‑пакеты (двоичные диффы между версиями), но поддержку полностью удалили в pacman 5.2.0 (октябрь 2019): по словам разработчиков, функция почти не использовалась, чаще замедляла обновление, чем экономила трафик, и содержала серьёзную уязвимость — вредоносная база пакетов в связке с дельтами позволяла выполнить произвольные команды (CVE-2019-18183).
Отказоустойчивость: что бывает, когда всё оборвалось
Ни один из двух менеджеров не является транзакционным на уровне файловой системы. Утверждения вида «pacman атомарен» неверны. Корректно говорить о механизмах восстановления, а не отката.
Debian: прерванная операция оставляет пакеты в состоянии unpacked или half‑configured. Диагностика — dpkg ‑audit, лечение — dpkg ‑configure ‑a, для сломанных зависимостей — apt ‑fix‑broken install.
Arch: прерванная транзакция может оставить частично записанные файлы и.pacnew. Если оборвалось ‑Syu — просто повторите pacman ‑Syu. Зависший файл блокировки /var/lib/pacman/db.lck удаляется руками (убедившись, что процесс действительно мёртв). Смена формата локальной базы между мажорными версиями обрабатывается pacman‑db‑upgrade. Встроенного отката нет — на практике арчеводы полагаются на снапшоты Btrfs/snapper и на кэш пакетов /var/cache/pacman/pkg/, из которого можно поставить предыдущую версию через pacman ‑U.
Из архитектурных улучшений последних лет: pacman 7.0 (июль 2024) вынес загрузку файлов в отдельный непривилегированный процесс, изолированный через Landlock (механизм ядра для ограничения доступа к файловой системе) и seccomp (фильтрация системных вызовов) — раньше скачивание шло от root. А релиз 7.1.0 (ноябрь 2025) сделал SigLevel = Required значением по умолчанию и для пакетов, и для баз.
Шпаргалка по командам
Задача | APT / dpkg | pacman |
Обновить списки пакетов | apt update | pacman ‑Sy ⚠ никогда отдельно |
Обновить систему | apt upgrade / apt full‑upgrade | pacman ‑Su |
Списки + обновление | apt update && apt full‑upgrade | pacman ‑Syu |
Установить | apt install foo | pacman ‑S foo |
Удалить | apt remove foo | pacman ‑R foo |
Удалить с конфигами и зависимостями | apt purge foo + apt autoremove | pacman ‑Rns foo |
Найти в репозитории | apt search foo | pacman ‑Ss foo |
Информация о пакете | apt show foo | pacman ‑Si foo / ‑Qi foo |
Список файлов пакета | dpkg ‑L foo | pacman ‑Ql foo |
Чей это файл | dpkg ‑S /путь | pacman ‑Qo /путь |
Поиск файла в неустановленных | apt‑file search | pacman ‑F / pkgfile |
Список «сирот» | apt autoremove | pacman ‑Qtdq |
Установить локальный файл | dpkg ‑i foo.deb | pacman ‑U foo.pkg.tar.zst |
Две ловушки, которые стоит выделить отдельно:
pacman ‑Sy без ‑u — описанное выше частичное обновление.
apt upgrade против apt full‑upgrade — обычный upgrade никогда не удаляет пакеты ради обновления и вместо этого «придерживает» их (kept back). full‑upgrade (он же dist‑upgrade) удалит то, что мешает. Отдельно в Ubuntu пакеты придерживаются механизмом phased updates: обновление выкатывается постепенно, начиная с 10% машин, и решение «попали ли вы в текущую волну» вычисляется локально из хеша machine‑id, версии и имени пакета — никаких данных на сервер не уходит.
Что из этого следует
Сводить сравнение к «pacman быстрее, apt надёжнее» — значит упускать суть. Оба менеджера оптимальны для своей задачи:
APT/dpkg спроектирован под мир, где релиз заморожен на несколько лет, пакеты активно патчатся дистрибутивом, версии библиотек сосуществуют, а система должна пережить обновление в полуавтоматическом режиме на тысяче серверов. Отсюда богатый словарь зависимостей, серьёзный решатель, скрипты сопровождающего, вопросы про конфиги и поэтапная выкатка обновлений.
pacman/libalpm спроектирован под мир, где софт поставляется максимально близко к upstream, система всегда актуальна целиком, а настройкой занимается сам пользователь. Отсюда простой формат, плоская база, отказ от мягких зависимостей, хуки вместо скриптов,.pacnew вместо диалогов — и жёсткий запрет на частичные обновления как цена всей этой простоты.
Разбираться в этом полезно даже если вы всю жизнь сидите на одном дистрибутиве: понимание того, что именно делает пакетный менеджер, превращает большинство «магических» ошибок обновления в понятные и решаемые.

