1

Есть ли способ запросить dpkg чтобы сказать, какие пакеты были добавлены / удалены после базовой установки системы?

Я использую Debian 5

1 ответ1

4

Насколько я могу судить, нет простого способа сделать это. База данных dpkg содержит только текущее состояние пакетов, поэтому любую историю придется выводить или анализировать из журналов.


Короткий ответ (он же однострочник для ленивых)

dpkg-query -f='${Package}\n' -W  | grep -vx "`grep 'Setting up' /var/log/installer/syslog | cut -d' ' -f8`"

объяснение

1. Получение списка пакетов, установленных установщиком

debian-installer записывает свои журналы в /var/log/installer . Там в syslog файл там , и мы можем grep , что посмотреть , что были установлены пакеты:

grep 'Setting up' /var/log/installer/syslog

Обратите внимание, что мы ищем настройки или распаковки, а не например. Выбор, так как мы хотим, чтобы все пакеты, в том числе установленные как зависимости. Нам нужно извлечь имена пакетов из этого:

grep 'Setting up' /var/log/installer/syslog | cut -d' ' -f8

2. Получение списка установленных на данный момент пакетов

Теперь нам нужен список установленных на данный момент пакетов, чтобы выполнить reverse grep . Мы хотим только имена пакетов, например. нет описаний, чтобы избежать отфильтровывания, поэтому простой dpkg -l не очень хорош. Вместо этого мы можем использовать dpkg-query :

dpkg-query -f='${Package}\n' -W

3. Фильтрация пакетов, установленных при запуске

Осталось только отфильтровать содержимое 1-го списка из 2-го списка. Для этого мы используем grep -vx . -v для "обратного", -x (или --line-regex) для "точного". Последний соответствует только целым строкам, что гарантирует, что мы отфильтруем, например. склонные , но не способности.

Итак, вот и все, воедино:

 # currently installed
 current="`dpkg-query -f='${Package}\n' -W`"
 # base install (let's also remove duplicates to make verification easier)
 base="`grep 'Setting up' /var/log/installer/syslog | cut -d' ' -f8 | sort | uniq`"
 # your answer
 extra="`echo "$current" | grep -vx "$base"`"
 removed="`echo "$base" | grep -vx "$current"`"

4. Проверка результатов

Чтобы проверить, правильно ли мы получили пакеты, мы можем посчитать строки:

 echo "$base" | wc -l         # 160
 echo "$current" | wc -l      # 1677
 echo "$extra" | wc -l        # 1517
 echo "$removed" | wc -l      # 0 (I used "netinst")

Обновление: если /var/log/installer нет

/var/log/installer удаляется из системы, если очищен installation-report пакета. В этом случае мы можем попытаться получить список пакетов, которые были загружены установщиком из самого старого файла /var/log/dpkg.log.* .

Есть 2 проблемы с этим:

  1. нет никакой гарантии, что информация, которая нам нужна, все еще там, так как эти файлы вращаются (все еще там в моем случае - установите на 2010-10-01 и с тех пор много обновлений)
  2. самый старый файл, вероятно, будет содержать журналы пакетов, устанавливаемых после начальной установки.

Мы ничего не можем поделать с (1). С помощью (2) мы можем вручную (возможно, по временным меткам) установить, какой пакет завершает установку с помощью debian-installer . В моем случае это был os-prober (который, я считаю, может быть распространенным в некоторых случаях из-за его отношения к grub).

Вот пример кода для получения $base с использованием этого метода:

 last_installed="os-prober"
 base_dpkglog="`zgrep ' install ' dpkg.log.8.gz | cut -d' ' -f4 | while read pkg; do 
     [ "$pkg" != "$last_installed" ] && echo $pkg || { echo $pkg; break; }
 done | sort | uniq`"

И быстрая проверка:

 echo "$base_dpkglog" | wc -l                    # 159
 echo "$base" | wc -l                            # 160
 diff -d <(echo "$base") <(echo "$base_dpkglog") # 31d30
                                                 # < dpkg

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .