Понадобилось распаковывать 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