Спор «deb или rpm» обычно ведут как спор дистрибутивов, хотя это разные вещи: формат пакета, менеджер зависимостей и репозиторий — три отдельных уровня. Debian-пакет можно поставить в систему с rpm-базой только вместе с dpkg, а RPM-пакет в Debian — только вместе с rpm. Полезнее понять, как оба формата устроены внутри: тогда чтение чужого spec-файла, разбор конфликта зависимостей и восстановление после неудачного обновления перестают быть магией.
Формат .deb: ar и два архива
Deb-пакет — это архив ar с тремя членами: debian-binary (версия формата, обычно 2.0), control.tar.* и data.tar.*. В control лежат метаданные и скрипты, в data — дерево файлов от корня. Сжатие может быть gzip, xz или zstd, поэтому «распаковать» пакет одним tar не получится: сначала нужен ar.
ar t package.deb
dpkg-deb -I package.deb
dpkg-deb -c package.deb | head -20
dpkg-deb -x package.deb /tmp/rootfs
dpkg-deb -I показывает control-файл: имя, версию, архитектуру, зависимости и сопровождающего. -c перечисляет содержимое с правами и владельцами, -x распаковывает данные без установки. В control-архиве кроме control лежат md5sums, список conffiles и скрипты preinst, postinst, prerm, postrm.
Формат .rpm: заголовки и cpio
RPM устроен сложнее: сигнатурный заголовок, основной заголовок с типизированными тегами и сжатый поток cpio. Заголовок содержит не только имя и версию, но и сотни полей: зависимости, скрипты, контрольные суммы файлов, флаги конфигурации, дату сборки. Именно поэтому rpm -qpi умеет отвечать на вопросы, для которых в deb-мире нужен dpkg-deb плюс разбор control.
rpm -qpi package.rpm
rpm -qpl package.rpm | head -20
rpm -qp --scripts package.rpm
rpm2cpio package.rpm | cpio -t | head -20
Полезный флаг -p означает «спросить файл, а не базу установленных пакетов». Без него rpm -qi nginx покажет сведения об уже установленном пакете. rpm2cpio превращает payload в поток cpio, который можно распаковать в любой каталог, не трогая систему.
Зависимости: разные философии
Оба менеджера требуют пакеты, но по-разному их называют. В deb-мире принято указывать имена пакетов и виртуальные предоставления: Depends: libc6 (>= 2.36), nginx-common (= 1.24.0-1). Есть Pre-Depends для случаев, когда пакет нужен до распаковки, Recommends и Suggests для необязательных связей, Breaks, Conflicts, Replaces и Provides.
В rpm-мире сильнее развита идея возможностей. Пакет предоставляет Provides: webserver, а другой требует Requires: webserver, и конкретное имя пакета уже не важно. Поддерживаются «богатые» зависимости вида Requires: (foo if bar), слабые связи Recommends и Supplements, а также зависимости по файлу — Requires: /usr/bin/python3. RPM умеет автоматически вычислять зависимости по ELF-библиотекам и интерпретаторам при сборке; в Debian этим занимается dpkg-shlibdeps, вызываемый из debhelper.
Базы данных и история операций
Debian хранит состояние в текстовом /var/lib/dpkg/status и в каталоге /var/lib/dpkg/info со списками файлов и контрольными суммами. RPM с версии 4.16 использует SQLite в /usr/lib/sysimage/rpm, а в старых системах — Berkeley DB в /var/lib/rpm. Отсюда разные способы восстановления: deb-базу можно прочитать и поправить текстовым редактором, rpm-базу — только утилитами rpm.
dpkg-query -W -f='${Package} ${Version}\n' | head
rpm -qa --last | head
tail -n 20 /var/log/dpkg.log
dnf history list | head
История в Debian — это /var/log/dpkg.log и /var/log/apt/history.log; откатить одну операцию штатно нельзя, но можно поставить прежнюю версию из кеша или снимка репозитория. В rpm-мире dnf history умеет undo и rollback для целой транзакции, пока пакеты доступны в репозитории. Это заметное практическое различие.
Скрипты и конфигурационные файлы
Оба формата позволяют выполнять код до и после установки. В deb это preinst, postinst, prerm, postrm; в rpm — %pre, %post, %preun, %postun, а также %pretrans и %posttrans. Скрипты запускаются от root и не должны содержать интерактивных вопросов: в автоматических обновлениях они приведут к зависанию.
Конфигурационные файлы защищены по-разному. dpkg спрашивает, что делать с изменённым conffile, и хранит решение в базе; rpm помечает файл как %config(noreplace) и при конфликте оставляет ваш вариант, а новый кладёт рядом с суффиксом .rpmnew; .rpmsave появляется, когда пакет всё же заменил файл. В обоих случаях после обновления стоит искать такие файлы и сравнивать их вручную.
Проверка целостности
Обе системы умеют сверять файлы с записанными контрольными суммами, но команды разные. Это первое, что стоит запускать при подозрении на повреждение после сбоя питания или неудачного обновления.
dpkg -V
debsums -c
rpm -Va
rpm -Vf /usr/bin/ssh
dpkg -V печатает изменённые файлы по данным из /var/lib/dpkg/info; debsums делает то же, но умеет проверять и пакеты без md5sums (ставится отдельно). rpm -Va проверяет все пакеты и кодирует расхождения буквами: 5 — изменилась сумма, S — размер, M — права, U — владелец. Флаг -f сужает проверку до файла.
Шпаргалка соответствий
- Установить локальный файл:
apt install ./pkg.debпротивdnf install ./pkg.rpm. - Владелец файла:
dpkg -S /usr/bin/awkпротивrpm -qf /usr/bin/awk. - Список файлов пакета:
dpkg -L nginxпротивrpm -ql nginx. - Зависимости:
apt-cache depends nginxпротивrpm -qR nginx. - Обратные зависимости:
apt-cache rdependsпротивrpm -q --whatrequires.
sudo dpkg -i package.deb
sudo apt install -f
sudo dnf install ./package.rpm
rpm -q --whatrequires 'libc.so.6()(64bit)' | head
Конвертация и совместимость
Утилита alien умеет превращать deb в rpm и обратно, но это инструмент для простых пакетов с данными, а не для системных библиотек. При конвертации теряются или ломаются скрипты, пути, генераторы зависимостей и раскладка файлов по /usr/lib с архитектурными суффиксами. Ставить такой пакет в рабочую систему — способ получить трудноуловимый конфликт. Если пакета нет в репозитории, правильнее собрать его штатно: dpkg-buildpackage для deb или rpmbuild для rpm.
Итог
deb и rpm решают одну задачу разными способами: первый делает ставку на простой текстовый формат и мощную систему виртуальных пакетов, второй — на богатые метаданные, возможности и транзакционную историю. Для администратора важнее не спор о форматах, а понимание слоёв: пакет, менеджер зависимостей, репозиторий. Зная dpkg-deb, rpm2cpio, dpkg -S и rpm -qf, вы разберёте любой чужой пакет, не устанавливая его.