Listen Sie die Pakete auf einem apt-basierten System nach Installationsdatum auf

104

Wie kann ich installierte Pakete nach Installationsdatum auflisten?

Ich muss das auf Debian / Ubuntu machen. Antworten für andere Distributionen wären auch nett.

Ich habe eine Menge Sachen installiert, um einen bestimmten Code zu kompilieren, und ich möchte eine Liste der Pakete erhalten, die ich installieren musste.

Elazar Leibovich
quelle
1
Ich habe ohne Glück nach dem passenden Erscheinungsdatum gegoogelt. Vielleicht hilft dieser Kommentar zukünftigen Googlern.
ThorSummoner
Ähnliche Frage bei askubuntu.com "Wie liste ich alle installierten Pakete auf ?" .
JamesThomasMoon1979

Antworten:

66

RPM-basierte Distributionen wie Red Hat sind einfach:

rpm -qa --last

Bei Debian und anderen dpkg-basierten Distributionen ist Ihr spezielles Problem ebenfalls einfach:

grep install /var/log/dpkg.log

In diesem Fall sollten Sie Folgendes versuchen, es sei denn, die Protokolldatei wurde gedreht:

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

Im Allgemeinen dpkgund aptscheinen nicht das Installationsdatum zu verfolgen, durch das Fehlen eines solchen Feldes im Gehen dpkg-queryman - Seite.

Und schließlich werden alte /var/log/dpkg.log.*Dateien durch Protokollrotation gelöscht, sodass nicht garantiert wird, dass Sie auf diese Weise den gesamten Verlauf Ihres Systems abrufen können.

Ein Vorschlag, der ein paar Mal vorkommt (zB dieser Thread ), ist das /var/lib/dpkg/infoVerzeichnis anzuschauen . Die Dateien dort deuten darauf hin, dass Sie Folgendes versuchen könnten:

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

Hier ist ein erster Durchgang, um Ihre Frage zu Auswahlen zu beantworten.

Liste der Pakete nach Datum erstellen

$ 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

Liste der installierten Pakete erstellen

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

Trete den 2 Listen bei

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

Aus irgendeinem Grund gibt es für mich nicht viele Unterschiede aus, daher könnte es einen Fehler oder eine ungültige Annahme darüber geben, was --get-selectionsbedeutet.

Sie können die Pakete natürlich einschränken, indem Sie find . -mtime -<days>oder verwenden head -n <lines>und das Ausgabeformat nach Ihren Wünschen ändern, z

$ 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

um nur die Auswahlen aufzulisten, die in den letzten 4 Tagen installiert (geändert?) wurden.

Sie könnten die sortBefehle wahrscheinlich auch entfernen , nachdem Sie die von verwendete Sortierreihenfolge überprüft dpkg --get-selectionsund den findBefehl effizienter gestaltet haben.

Mikel
quelle
8
Normalerweise mag ich apt-getmehr als rpm, aber jetzt bekommt Debian -1, weil das Installationsdatum nicht in der Datenbank gespeichert wurde. Der Debian-Trick beinhaltet alle installierten Pakete, nicht nur die ausgewählten Pakete, aber es ist ein guter Anfang.
Elazar Leibovich
Für Debian erhalten Sie weniger Cruft (entfernt half-installedEinträge), wenn Sie Folgendes tun:grep install\ /var/log/dpkg.log
Pierz
@Mikel - Tolle Antwort. Ich habe die Datei 'gather /var/lib/dpkg/info/*.list file info' erweitert und Code hinzugefügt, um alle Pakete außer den "Top-Level-Paketen" (atp-Pakete, von denen keine anderen atp-Pakete abhängen) herauszufiltern. Dieser < askubuntu.com/a/948532/723997 > Beitrag beantwortet die Frage "Wie kann ich den Verlauf von apt-get install-Befehlen anzeigen, die ich manuell ausgeführt habe? ".
Craig Hicks
1
Debian / Ubuntu: grep " install " /var/log/dpkg.loglistet nur die "install" -Zeilen auf, anstatt auch die "status" -Zeilen anzuzeigen.
Dessert
Wenn weder apt noch dpkg store datetime installieren / modifizieren, scheint mir das 2019 ziemlich inakzeptabel zu sein. Wie ist das der Fall?
Theferrit32
20

Mikel hat gezeigt, wie das auf dpkg-Ebene geht . Insbesondere /var/lib/dpkg/info/$packagename.listwird erstellt, wenn das Paket installiert wird (und danach nicht mehr geändert wird).

Wenn Sie die APT-Tools verwendet haben (was Sie vermutlich getan haben, weil Sie sich Sorgen um automatisch im Vergleich zu manuell installierten Paketen machen), gibt es einen Verlauf in /var/log/apt/history.log. Solange es nicht entfernt wurde, werden alle APT-Installationen, -Upgrades und -Entfernungen mit einer Anmerkung für Pakete protokolliert, die als automatisch installiert markiert sind. Dies ist ein relativ neues Feature, das in APT 0.7.26 eingeführt wurde, so dass es in Debian in squeeze erschien. In Ubuntu hat 10.04 history.logaber die automatisch installierte Annotation ist erst ab 10.10 vorhanden.

Gilles
quelle
1
Wie Mikel betonte: "Und schließlich werden alte /var/log/dpkg.log.* -Dateien durch Protokollrotation gelöscht, so dass auf diese Weise nicht garantiert wird, dass Sie den gesamten Verlauf Ihres Systems erhalten." In dieser < askubuntu.com/a/948532/723997 > Antwort erfahren Sie , wie Sie die aktuellen Top-Level-Pakete erkennen (dh diejenigen, von denen kein anderes Paket abhängt)
Craig Hicks
5

Rau, aber funktioniert:

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
Dulantha
quelle
2
Boo, zischen Sie für das Parsen der Ausgabe von ls. Unter mywiki.wooledge.org/ParsingLs finden Sie Hinweise dazu, warum dies gefährlich / von Natur aus fehlerhaft ist. Die sicherere Option besteht darin, entweder einen Stream zu verwenden find -printfoder stat --formateinen Stream zu generieren, der eindeutig analysiert werden kann.
Charles Duffy
@CharlesDuffy Netter Link, aber der Einfachheit halber ls -al --time-style=long-isosollte die Verwendung hilfreich sein. Außerdem ist es wahrscheinlich ungewöhnlich, dass jemand ein APT-Paket mit \n\t\r\vseinem Namen benennt .
not2qubit
4

Die /var/log/apt/history.logDatei hat ein umständliches Format IMHO.

Startdatum: {Datum} {Uhrzeit} Befehlszeile: {Befehl} {Optionen ...} Installieren: {Paket (Version)}, ..., {Paket (Version)}, ... Enddatum: {Datum } {Zeit}

Ich hätte es vorgezogen, wenn die Protokolldatei stärker formatiert gewesen wäre

{Datum} {Uhrzeit} {Tab} {Paket} {Tab} {Version} {Tab} {Befehl} {Optionen} \ n

oder einige XML-Dateien, die nicht nur ein {Paket}, sondern auch {Abhängigkeiten} enthalten.

In der derzeit implementierten Version können Sie die gesuchten Informationen ermitteln, es ist jedoch eine gewisse forensische Verarbeitung erforderlich, um die Details zu extrahieren.

Saint DanBert
quelle
3

Dies funktioniert für mich auf einem Debian-System. Ich vermute, dass sich das Dateiformat seit 2011 geändert hat. Dieses System ist ziemlich neu, daher würde ich nicht erwarten, dass dies auf einem älteren System funktioniert, obwohl dies möglicherweise nur das Entpacken der Protokolle und die Verwendung erfordert Ein Glob, der sich auf alle bezieht.

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

Die ersten beiden Felder in jeder Zeile der Datei /var/log/dpkg.logsind Datum und Uhrzeit. Beachten Sie den nachgestellten Bereich mit install im grep-Teil. Dies liegt daran, dass Upgrades Installationen auslösen können, aber wenn ich das richtig verstanden habe, wollten Sie wissen, was von den Benutzern installiert wurde.

Amias
quelle
1
Genau das, was ich tue. Einfach. Sie können jedoch zgrep verwenden und alle Ihre .gz-Protokolle werden wie zgrep 'install' /var/log/dpkg.log* durchsucht. Platzieren Sie das Leerzeichen vor dem Wort "install", um diese lästigen "halben Installationen" zu verhindern. Ich musste cut -f1,5 verwenden, um das Feld für den Paketnamen zu erhalten. Natürlich drehen sich irgendwann die alten Protokolle heraus.
GeoO
2

Hier ist der Einzeiler, den jeder möchte und braucht:

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

Das Ergebnis zeigt alle (neu) installierten und aktualisierten Pakete in chronologischer Reihenfolge.

Die Zeilenerklärung:

  • ls -1t- Holen Sie sich alle dpkg.log*Dateinamen in chronologischer Reihenfolge
  • zcat -f- WENN die Datei vom Typ gzip ist, dekomprimieren Sie sie. Anderenfalls leiten Sie den Inhalt weiter.
  • tac- Kehren Sie die Ausgabe von cat zeilenweise um, um sicherzustellen, dass wir die richtige chronologische Reihenfolge erhalten.
  • grep- Überprüfen Sie nur, ob Pakete installiert oder aktualisiert sind .
  • awk -F ':a'- Trennen Sie das Architekturfeld vom Paketnamen
  • column -t - drucke die durch Leerzeichen getrennten Spalten schön aus

Man möchte natürlich einen Alias ​​dafür erstellen, aber das ist leider nicht möglich, da awk sowohl von einfachen als auch von doppelten Anführungszeichen abhängt. In dieser Hinsicht ist dies am besten in ein Bash-Skript einzufügen und dort, wo das :Trennzeichen für andere Architekturen in der Feldspalte besser gehandhabt wird .

Die Ausgabe ist:

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

Nachteil:

  • Wie oben gezeigt, funktioniert es nur auf der ARM-Architektur und muss für das Architekturfeldtrennzeichen geringfügig geändert werden
  • Muss für einen einfachen Alias ​​in ein Skript eingefügt werden
  • Wurde nicht auf anderen * nix-Systemen getestet
not2qubit
quelle
1

Beachten Sie dies, weil Sie erwähnen, dass andere Verteilungsantworten willkommen sind. rpm verfügt über eine große Anzahl von Ausgabeformat-Tags, von denen eines INSTALLTIME ist. (Am wgetBeispiel)

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

Dies kann auf verschiedene Arten formatiert werden. Ich benutze es so:

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

Auf diesen beiden Seiten finden Sie zahlreiche nützliche Informationen zum Lösen von Problemen mit RPM-Metadaten:

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

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

Wenn Sie diese Informationen sortieren, erhalten Sie eine funktionierende Lösung für Ihr Problem.

Jonathan Swift
quelle
1

GNU / Linux Debian hat keine eingebauten Werkzeuge für dieses Problem, aber alle Informationen über Programme, die auf die Standardart installiert wurden, werden in Dateien mit dem Programmnamen list im Verzeichnis / var / lib / dpkg / info / gespeichert . Es gibt dort jedoch keine Informationen zu manuell installierten Programmen.


Eine lange einzeilige Lösung :

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

Erklärung :

  1. ls -rtgibt Dateien sortiert nach Datumsänderung in umgekehrter Reihenfolge aus, dh mit den neuesten Dateien am Ende der Liste.
  2. stat druckt das Datum der Datei in lesbarer Form.
  3. printf Zeigt den Paketnamen und das Datum der letzten Änderung an.
  4. Die forgesamte Schleife gibt Paketnamen aus und datiert vom ältesten zum neuesten.

Ausgabebeispiel (abgeschnitten):

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

Der Hauptfehler dieser Lösung ist, dass sie in der Produktion nicht gut getestet wurde.

PADYMKO
quelle
Dies ist eine schöne Lösung, die den Job fast erledigt. Es ist nur ein Nachteil, dass (1) es sehr langsam ist und (2) nur angezeigt wird, wann ein Paket zuletzt aktualisiert wurde , und keine der vorherigen Versionen. Dies ist natürlich kein Problem des Einzeilers, aber wie dpkg die Geschichte nicht im Auge behält /var/lib/dpkg/info/. Dies ist auch der Grund, warum die Verwendung /var/log/dpkg.log*bevorzugt sein kann.
not2qubit
1

Es ist rau, funktioniert aber genauso schnell wie andere Lösungen. Das Datumsformat ist yyyymmddhhmmss, was bedeutet, dass ein bisschen oder Umordnen und Entfernen des Formats zu einer Zahl führt, die sortiert werden kann.

Vielen Dank an die anderen Lösungen, diese Liste Paketnamen in der Reihenfolge der Installation, die in einem zum Kopieren erstellten Betriebssystem verwendet werden könnten.

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}'
Alexander-Höhle
quelle
Willkommen bei Alexander-Cave! Bitte fügen Sie einige Zeilen der Ausgabe hinzu, damit die Benutzer sehen können, welche Art von Ausgabe zu erwarten ist.
not2qubit