web-dev-qa-db-fra.com

Liste des packages sur un système basé sur apt par date d'installation

Comment puis-je lister les packages installés par date d'installation?

Je dois le faire sur debian/ubuntu. Les réponses pour d'autres distributions seraient également bien.

J'ai installé beaucoup de choses pour compiler un certain morceau de code, et je veux obtenir une liste des packages que j'ai dû installer.

106

Les distributions basées sur RPM comme Red Hat sont faciles:

rpm -qa --last

Sur Debian et d'autres distributions basées sur dpkg, votre problème spécifique est également simple:

grep install /var/log/dpkg.log

Sauf si le fichier journal a été pivoté, auquel cas vous devez essayer:

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

En général, dpkg et apt ne semblent pas suivre la date d'installation, étant donné l'absence d'un tel champ dans le dpkg-query page de manuel.

Et finalement vieux /var/log/dpkg.log.* les fichiers seront supprimés par rotation du journal, de sorte que cette façon n'est pas garantie de vous donner l'historique complet de votre système.

Une suggestion qui apparaît plusieurs fois (par exemple ce fil ) est de regarder le /var/lib/dpkg/info répertoire. Les fichiers suggèrent que vous pourriez essayer quelque chose comme:

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

Pour répondre à votre question sur les sélections, voici un premier passage.

construire la liste des packages par dates

$ 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

construire la liste des packages installés

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

rejoindre les 2 listes

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

Pour une raison quelconque, cela n'imprime pas beaucoup de différences pour moi, il peut donc y avoir un bogue ou une hypothèse invalide sur ce que --get-selections veux dire.

Vous pouvez évidemment limiter les packages en utilisant find . -mtime -<days> ou head -n <lines>, et modifiez le format de sortie comme vous le souhaitez, par exemple.

$ 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

pour répertorier uniquement les sélections qui ont été installées (modifiées?) au cours des 4 derniers jours.

Vous pourriez probablement aussi supprimer les commandes sort après avoir vérifié l'ordre de tri utilisé par dpkg --get-selections et rendre la commande find plus efficace.

68
Mikel

Mikel a montré comment faire cela au niveau du dpkg . En particulier, /var/lib/dpkg/info/$packagename.list est créé lorsque le package est installé (et non modifié par la suite).

Si vous avez utilisé les outils APT (ce que vous avez probablement fait puisque vous êtes préoccupé par les packages installés automatiquement ou manuellement), il y a un historique dans /var/log/apt/history.log. Tant qu'il n'a pas pivoté, il garde une trace de toutes les installations, mises à niveau et suppressions APT, avec une annotation pour les packages marqués comme installés automatiquement. Il s'agit d'une fonctionnalité assez récente, introduite dans APT 0.7.26, donc dans Debian il est apparu dans squeeze. Dans Ubuntu, 10.04 a history.log mais l'annotation installée automatiquement n'est pas présente avant 10h10.

Rugueux, mais fonctionne:

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

Le /var/log/apt/history.log Le fichier a un format maladroit à mon humble avis.

Date de début: {date} {heure} Ligne de commande: {commande} {options ...} Installation: {package (version)}, ..., {package (version)}, ... Date de fin: {date } {temps}

J'aurais préféré un enregistrement formaté plus en fichier journal

{date} {heure} {tab} {package} {tab} {version} {tab} {commande} {options}\n

ou du XML montrant non seulement un {package} mais aussi des {dépendances}.

Telle qu'elle est actuellement implémentée, vous pouvez découvrir les informations que vous recherchez, mais cela nécessite un traitement médico-légal pour extraire les détails.

4
Saint DanBert

Cela fonctionne pour moi sur un système Debian, je suppose que le format de fichier a changé depuis 2011. Ce système est assez récent, donc je ne m'attendrais pas à ce que cela fonctionne sur un système plus ancien, bien que cela puisse juste nécessiter de décompresser les journaux et d'utiliser un glob pour faire référence à chacun d'eux.

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

Les deux premiers champs de chaque ligne du fichier /var/log/dpkg.log sont la date et l'heure. Notez l'espace de fin avec l'installation dans la partie grep, c'est parce que les mises à niveau peuvent déclencher des installations mais si j'ai bien compris, vous vouliez savoir ce qui était installé par les utilisateurs.

3
Amias

Voici le one-liner que tout le monde veut et a besoin:

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

Le résultat montrera tous les packages (nouvellement) installés et mis à niveau dans l'ordre chronologique ordre.

L'explication de la ligne:

  • ls -1t - Avoir tout dpkg.log* noms de fichiers par ordre chronologique
  • zcat -f - SI le fichier est de type gzip puis décompressez-le, - ELSE il suffit de transmettre le contenu.
  • tac - Sortie inverse de cat , ligne par ligne pour s'assurer que nous obtenons l'ordre chronologique correct.
  • grep - Vérifier uniquement les packages installés ou de mise à niveau .
  • awk -F ':a' - Séparez le champ de l'architecture du nom du package
  • column -t - joliment imprimer les colonnes séparées par un espace

On aimerait bien sûr faire un alias pour cela, mais malheureusement ce n'est pas possible car awk dépend à la fois des guillemets simples et doubles. À cet égard, il est préférable de le mettre dans un script bash et où le : le séparateur est mieux géré pour les autres architectures dans la colonne champ.

La sortie est:

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

Inconvénient:

  • Comme indiqué ci-dessus, il ne fonctionne que sur l'architecture ARM et nécessite une légère modification pour le séparateur de champ d'architecture
  • Besoin d'être mis dans un script pour un alias facile
  • N'a pas été testé sur d'autres systèmes * nix
2
not2qubit

GNU/Linux Debian n'a pas d'outils intégrés pour ce problème, mais toutes les informations sur les programmes installés de la manière standard sont enregistrées dans des fichiers avec program-name.list à l'emplacement /var/lib/dpkg/info/. Mais il n'y a aucune information sur les programmes installés manuellement là-bas.


ne solution longue ligne unique:

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

Explication:

  1. ls -rt affiche les fichiers triés par modification de date dans l'ordre inverse, c'est-à-dire avec les fichiers les plus récents à la fin de la liste.
  2. stat imprime la date du fichier sous une forme lisible par l'homme.
  3. printf affiche le nom du package et la date de sa dernière modification.
  4. La boucle for dans son ensemble imprime les noms et dates des packages du plus ancien au plus récent.

Exemple de sortie (tronqué):

.........................................
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

Le principal défaut de cette solution est qu'elle n'est pas bien testée en production.

1
PADYMKO

C'est rude, mais fonctionne aussi rapidement que d'autres solutions. Le format de la date est aaaammjjhhmmss, ce qui signifie qu'un peu ou la réorganisation et la suppression du format entraînent un nombre qui peut être trié.

Un grand merci aux autres solutions, cette liste des noms de packages dans l'ordre d'installation qui pourrait être utilisé dans un système d'exploitation construit pour faire une copie.

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

Notant cela parce que vous mentionnez que d'autres réponses de distribution sont les bienvenues. rpm possède un large ensemble de balises de format de sortie, dont INSTALLTIME. (En utilisant wget comme exemple)

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

Cela peut être formaté de plusieurs manières. Je l'utilise de cette façon:

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

Ces deux pages contiennent une tonne d'informations utiles sur la résolution des problèmes de métadonnées RPM:

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

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

Le tri de ces informations vous donnerait une solution de travail pour votre problème.

1
Jonathan Swift