Скрипт, разбирающий deb-пакеты

Понадобилось распаковывать deb-пакеты, чтобы вытащить из них некоторые программулины, для других версий Linux не собранные. Решил распаковку deb-пакетов автоматизировать и написать скрипт, распаковывающий, а точнее разбирающий на составные части все deb-пакеты, находящиеся в текущем каталоге.

Кратко и по рабоче-крестьянски, что такое deb-пакет. Фактически, это архив формата ar, содержащий бинарные файлы программы, скрипты, необходимые пакетному менеджеру Debian для установки/удаления пакета и всякую служебную информацию, вроде контрольных сумм и прочего.
Нас интересуют бинарные файлы и неплохо бы посмотреть на предустановочные скрипты, ну мало ли чего там интересного и важного обнаружится. Установочные скрипты внутри архива ar сжаты в архив control.tar.gz, а вот бинарники находятся в архиве data.tar.??, где вместо ?? может быть .gz, .xz и т.д., в зависимости от того, что для сжатия бинарников было использовано. В архиве data сохранена структура каталогов, идентичная каталогам в системе, куда будет установлен пакет, примерно как в пакетах Slackware (только структура каталогов, естественно, специфична для Debian-подобных Linux). В архиве control.tar.gz могут содержаться скрипты конфигурирования, из которых наиболее интересны preinst, выполняемый на Debian перед распаковкой пакета, и postinst, выполняемый, когда пакетный менеджер распаковал бинарники в целевую систему. Естественно, просто так их выполнять не советую, но если делать из deb-пакета пакет Slackware, то не лишним будет с этими скриптами ознакомиться и буде там что нужное, передрать в doinst.sh

Скрипт

Определим основные переменные:
#!/bin/bash

DATADIR="./data" #директория, куда класть архивы с бинарниками
CONTROLDIR="./control" #... с управляющими скриптами
CURDIR="" #Текущая директория

Вывод краткой справки по использованию скрипта:

if [ "$1" == "-h" ]; then #print help
    echo "Unpacking all *.deb packages in current directory"
    echo "use" `basename "$0"` "[-c]"
    echo "-c - delete files in out-dirs"
    exit
fi

Выводим информационное сообщение и создаем каталоги для хранения архивов с бинарниками и управляющими скриптами:

echo "Unpacking all *.deb packages in current directory"

echo "Making out-dirs... $DATADIR $CONTROLDIR"
mkdir $DATADIR
mkdir $CONTROLDIR

Если при запуске скрипта был указан ключ -c, то очищаем содержимое директорий для хранения распакованных файлов:

if [ "$1" == "-c" ]; then 
    echo "Clear out-dirs..."
    CURDIR=`pwd`
    cd $DATADIR
    rm *
    cd $CURDIR
    cd $CONTROLDIR
    rm *
    cd $CURDIR
fi

С помощью команды find получим список всех deb-пакетов (*.deb) в текущей директории:

echo "Processing:"
F=`find . -name "*.deb" -type f`

где:
. (точка) — указание команде find искать в текущем каталоге.
-name — после этого ключа задается нужная нам маска файла ("*.deb")
-type f — искать только файлы (не каталоги, подпадающие под шаблон).

Результат отправляется (``) в переменную $F, которую обрабатываем в следующем цикле for:

for FILE in $F
do
...
done

Что делаем в цикле:
Вызываем архиватор ar с параметром t, это выведет список файлов в архиве, потом при помощи grep получаем имя архива data с бинарниками (напомню, оно разное может быть, в зависимости от того, чем бинарники сжаты):

DATAPKG=`ar t ${FILE}|grep "data"`

Аналогично поступаем и с архивом control, содержащим управляющие скрипты:

CONTROLPKG=`ar t ${FILE}|grep "control"`

Получаем имя deb-пакета без расширения (ключ -s ".deb" команды basename):

BASENAME=`basename -s ".deb" ${FILE}`

И расширения для содержащихся в deb-пакете архивов с бинарниками и скриптами:

EXTDATA=`echo $DATAPKG|sed 's/data//g'`
EXTCONTROL=`echo $CONTROLPKG|sed 's/control//g'`
echo "${FILE} : $DATAPKG, $CONTROLPKG"

Идея в том, чтобы при разборе пакета поименовать каждый архив также, каково имя пакета, присвоив правильное расширение, чтоб, если пакет не один, было понятно — какой архив от какого пакета, и чтоб они друг друга не затерли.

Вытаскиваем архивы из пакета:
ar -p "$BASENAME.deb" $DATAPKG > "$DATADIR/$BASENAME$EXTDATA"
ar -p "$BASENAME.deb" $CONTROLPKG > "$CONTROLDIR/$BASENAME$EXTCONTROL"

После запуска скрипта в каталоге, содержащем deb-пакеты, будкт созданы два подкаталога, содержащие архивы с бинарниками и архивы с инсталляционными скриптами.
Их уже можно распаковать стандартными tar’ом и gzip’ом или посмотреть их содержимое с помощью mc

Скрипт целиком

На PasteBin
Скачать с Mega.nz

Источники

1. Архиватор ar
2. Структура deb-пакета
3. Цикл for
4. Распаковка пакета deb
5. basename --help

Заметка в PDF

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *