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.
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.
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
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.
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.
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 chronologiquezcat -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 packagecolumn -t
- joliment imprimer les colonnes séparées par un espaceOn 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:
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:
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.stat
imprime la date du fichier sous une forme lisible par l'homme.printf
affiche le nom du package et la date de sa dernière modification.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.
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}'
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.