it-swarm-ru.tech

Список пакетов в системе на основе apt по дате установки

Как я могу вывести список установленных пакетов по дате установки?

Мне нужно сделать это в Debian/Ubuntu. Ответы для других дистрибутивов также будут хорошими.

Я установил много вещей для компиляции определенного фрагмента кода и хочу получить список пакетов, которые мне пришлось установить.

106
Elazar Leibovich

Дистрибутивы на основе RPM, такие как Red Hat, просты:

rpm -qa --last

В Debian и других дистрибутивах на основе dpkg ваша конкретная проблема также проста:

grep install /var/log/dpkg.log

Если файл журнала не был повернут, в этом случае вы должны попробовать:

grep install /var/log/dpkg.log /var/log/dpkg.log.1

В общем, dpkg и ​​apt, похоже, не отслеживают дату установки из-за отсутствия какого-либо такого поля в dpkg-query справочная страница.

И в конце концов старый /var/log/dpkg.log.* файлы будут удалены путем ротации журналов, поэтому этот способ не гарантирует полную историю вашей системы.

Одно предложение, которое появляется несколько раз (например, эта тема ), это посмотреть на /var/lib/dpkg/info каталог. Файлы там предлагают вам попробовать что-то вроде:

ls -t /var/lib/dpkg/info/*.list | sed -e 's/\.list$//' | head -n 50

Чтобы ответить на ваш вопрос о выборе, вот первый проход.

построить список пакетов по датам

$ find /var/lib/dpkg/info -name "*.list" -exec stat -c $'%n\t%y' {} \; | \
    sed -e 's,/var/lib/dpkg/info/,,' -e 's,\.list\t,\t,' | \
    sort > ~/dpkglist.dates

построить список установленных пакетов

$ dpkg --get-selections | sed -ne '/\tinstall$/{s/[[:space:]].*//;p}' | \
    sort > ~/dpkglist.selections

присоединиться к 2 спискам

$ join -1 1 -2 1 -t $'\t' ~/dpkglist.selections ~/dpkglist.dates \
    > ~/dpkglist.selectiondates

По какой-то причине для меня не очень много различий, поэтому может быть ошибка или неверное предположение о том, что --get-selections средства.

Очевидно, вы можете ограничить пакеты либо с помощью find . -mtime -<days> или head -n <lines> и ​​измените формат вывода по своему усмотрению, например,.

$ find /var/lib/dpkg/info -name "*.list" -mtime -4 | \
    sed -e 's,/var/lib/dpkg/info/,,' -e 's,\.list$,,' | \
    sort > ~/dpkglist.recent

$ join -1 1 -2 1 -t $'\t' ~/dpkglist.selections ~/dpkglist.recent \
    > ~/dpkglist.recentselections

перечислить только те варианты, которые были установлены (изменены?) за последние 4 дня.

Вы также можете удалить команды sort после проверки порядка сортировки, используемого dpkg --get-selections и ​​сделайте команду find более эффективной.

68
Mikel

Микель показал, как это сделать на уровне dpkg . В частности, /var/lib/dpkg/info/$packagename.list Создается при установке пакета (и не изменяется впоследствии).

Если вы использовали инструменты APT (что вы, вероятно, и сделали, так как беспокоитесь об автоматических или устанавливаемых вручную пакетах), в /var/log/apt/history.log Есть история, пока она не ' Отвернутый, он отслеживает все APT установки, обновления и удаления, с аннотацией для пакетов, помеченных как автоматически установленные. Это довольно недавняя функция, представленная в APT 0.7.26, поэтому в Debian он появился в squeeze. В Ubuntu 10.04 имеет history.log, Но автоматически установленная аннотация отсутствует до 10.10.

20

Грубо, но работает:

for fillo in `ls -tr /var/lib/dpkg/info/*.list` ; 
    do basename ${fillo} | sed 's/.list$//g' ; 
done > forens.txt

ls -ltr /var/lib/dpkg/info/*.list > forentime.txt

for lint in `cat forens.txt` ; do 
    echo -n "[ ${lint} Installed ] : " ; 
    echo -n "`grep /${lint}.list forentime.txt | awk '{ print $6, $7, $8 }'` : " ; 
    ( ( grep -A3 " ${lint}$" /var/lib/apt/extended_states | \
        grep '^Auto' > /dev/null ) && echo "Auto" ) || echo "Manual" ; 
done > pkgdatetime.txt
6
Dulantha

/var/log/apt/history.log файл имеет неудобный формат ИМХО.

Дата начала: {дата} {время} Командная строка: {команда} {опции ...} Установка: {пакет (версия)}, ..., {пакет (версия)}, ... Дата окончания: {дата } {время}

Я бы предпочел более отформатированную запись в лог-файле

{Дата} {время} {вкладка} {пакет} {вкладка} {версия} {вкладка} {команда} {опции}\п

или некоторый XML, показывающий не только {пакет}, но и любые {зависимости}.

В настоящее время реализовано, вы можете найти информацию, которую вы ищете, но это требует некоторой судебной обработки для извлечения деталей.

4
Saint DanBert

Это работает для меня в системе Debian, я предполагаю, что формат файла изменился с 2011 года. Эта система довольно свежа, поэтому я не ожидаю, что это сработает на более старой системе, хотя для этого может потребоваться просто распаковать журналы и использовать шар, чтобы обратиться ко всем из них.

grep 'install ' /var/log/dpkg.log.1 | sort | cut -f1,2,4 -d' '

Первые два поля в каждой строке файла /var/log/dpkg.log - это дата и время. Обратите внимание на завершающее пространство с установкой в ​​части grep, это потому, что обновления могут инициировать установку, но если я правильно понял, вы хотели знать, что было установлено пользователями.

3
Amias

Вот одна строка, которую каждый хочет и нуждается:

for x in $(ls -1t /var/log/dpkg.log*); do zcat -f $x |tac |grep -e " install " -e " upgrade "; done |awk -F ":a" '{print $1 " :a" $2}' |column -t

В результате будут показаны все (недавно) установленные и обновленные пакеты в хронологическом порядке. приказ.

строка объяснения:

  • ls -1t - получить все dpkg.log* имена файлов в хронологическом порядке
  • zcat -f - ЕСЛИ файл имеет тип gzip , то распакуйте его, - ELSE просто передать содержимое.
  • tac - Обратный вывод cat , построчно, чтобы убедиться, что мы получаем правильный хронологический порядок.
  • grep - Проверять только установленные или пакеты обновления ,.
  • awk -F ':a' - Отделить поле архитектуры от имени пакета
  • column -t - красивая печать столбцов, разделенных пробелом

Конечно, хотелось бы создать для этого псевдоним, но, к сожалению, это невозможно, так как awk зависит как от одинарных, так и от двойных кавычек. В связи с этим это лучше всего поместить в скрипт bash и где : разделитель лучше обрабатывается для других архитектур в столбце поля.

Результат:

2018-03-06  18:09:47  upgrade  libgomp1                     :armhf  6.3.0-18+rpi1                 6.3.0-18+rpi1+deb9u1
2018-03-05  15:56:23  install  mpg123                       :armhf  <none>                        1.23.8-1
2018-03-05  15:56:23  install  libout123-0                  :armhf  <none>                        1.23.8-1
2018-01-22  17:09:45  install  libmailtools-Perl            :all    <none>                        2.18-1
2018-01-22  17:09:44  install  libnet-smtp-ssl-Perl         :all    <none>                        1.04-1

Минус:

  • Как показано выше, он работает только на архитектуре ARM) и требует небольшой модификации для разделителя полей архитектуры
  • Нужно вставить в скрипт для легкого псевдонима
  • Не был протестирован в других системах * nix
2
not2qubit

В GNU/Linux Debian нет встроенных инструментов для этой проблемы, но вся информация о программах, установленных стандартным способом, сохраняется в файлах с program-name.list в расположении /var/lib/dpkg/info/. Но там нет информации об установленных вручную программах.


длинное однолинейное решение:

for file_list in `ls -rt /var/lib/dpkg/info/*.list`; do \
    stat_result=$(stat --format=%y "$file_list"); \
    printf "%-50s %s\n" $(basename $file_list .list) "$stat_result"; \
done

Объяснение:

  1. ls -rt выводит файлы, отсортированные по дате изменения в обратном порядке, , т.е. с самыми новыми файлами в конце списка.
  2. stat печатает дату файла в удобочитаемой форме.
  3. printf отображает имя пакета и дату его последнего изменения.
  4. Цикл for в целом печатает имена пакетов и даты от самых старых до самых новых.

Пример вывода (усечено):

.........................................
gnome-system-log                            2016-09-17 16:31:58.000000000 +0300
libyelp0                                    2016-09-17 16:32:00.000000000 +0300
gnome-system-monitor                        2016-09-17 16:32:00.000000000 +0300
Yelp-xsl                                    2016-09-17 16:32:01.000000000 +0300
Yelp                                        2016-09-17 16:32:03.000000000 +0300
gnome-user-guide                            2016-09-17 16:32:18.000000000 +0300
libapache2-mod-dnssd                        2016-09-17 16:32:19.000000000 +0300
.........................................
linux-compiler-gcc-4.8-x86                  2017-02-26 20:11:02.800756429 +0200
linux-headers-3.16.0-4-AMD64                2017-02-26 20:11:10.463446327 +0200
linux-headers-3.16.0-4-common               2017-02-26 20:11:17.414555037 +0200
linux-libc-dev:AMD64                        2017-02-26 20:11:21.126184016 +0200
openssl                                     2017-02-26 20:11:22.094098618 +0200
unzip                                       2017-02-26 20:11:23.118013331 +0200
wireless-regdb                              2017-02-26 20:11:23.929949143 +0200
nodejs                                      2017-02-26 20:11:33.321424052 +0200
nasm                                        2017-02-28 16:41:17.013509727 +0200
librecode0:AMD64                            2017-03-01 10:38:49.817962640 +0200
libuchardet0                                2017-03-01 10:41:10.860098788 +0200
tree                                        2017-03-04 14:32:12.251787763 +0200
libtar0                                     2017-03-07 09:51:46.609746789 +0200
libtar-dev                                  2017-03-07 09:51:47.129753987 +0200

Основным недостатком этого решения является то, что оно недостаточно хорошо протестировано на производстве.

1
PADYMKO

Это грубо, но работает так же быстро, как и другие решения. Формат даты - ггггммддччммсс, что означает, что бит или переупорядочение и удаление формата приводят к числу, которое можно отсортировать.

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

find /var/lib/dpkg/info -name "*.list" -exec stat -c $'%n\t%y' {} \; \
| sed -e 's,/var/lib/dpkg/info/,,' -e 's,\.list\t,\t,' \
| sort | awk '{print $2$3" "$1}' | sed '0,/RE/s/-//' \
| sed '0,/RE/s/-//' | sed '0,/RE/s/://' | sed '0,/RE/s/://' \
| sed '0,/RE/s/\\.//' | sed 's/:armhf//' | sort | awk '{print $2}'
1
Alexander Cave

Отмечая это, вы упоминаете, что приветствуются ответы на другие вопросы. rpm имеет большой набор тегов выходного формата, одним из которых является INSTALLTIME. (Используя wget в качестве примера)

rpm -qi wget --qf "%{NAME},%{INSTALLTIME}\n" | tail -n 1
wget,1454014156

Это может быть отформатировано несколькими способами. Я использую это таким образом:

rpm -qi wget --qf "%{NAME},%{INSTALLTIME:date}\n" | tail -n 1
wget,Thu 28 Jan 2016 03:49:16 PM EST

На этих двух страницах содержится масса полезной информации по решению проблем метаданных RPM:

http://www.rpm.org/max-rpm/s1-rpm-query-parts.html

http://www.rpm.org/max-rpm/s1-rpm-query-handy-queries.html

Сортировка этой информации даст вам рабочее решение вашей проблемы.

1
Jonathan Swift