Lista paket i ett apt-baserat system efter installationsdatum

Hur kan jag lista installerade paket efter installationsdatum?

Jag måste göra detta på debian / ubuntu. Svar på andra distributioner skulle också vara trevliga.

Jag installerade en hel del saker för att kompilera en viss kod och jag vill få en lista över de paket som jag var tvungen att installera.

Kommentarer

Svar

RPM-baserade distributioner som Red Hat är enkla:

rpm -qa --last 

På Debian och andra dpkg-baserade distributioner är ditt specifika problem också lätt:

grep install /var/log/dpkg.log 

Såvida inte loggfilen har roterats, i vilket fall du ska försöka:

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

I allmänhet verkar dpkg och apt inte spåra installationsdatumet, eftersom det saknas något sådant fält i dpkg-query man-sida.

Och så småningom kommer gamla /var/log/dpkg.log.* -filer att raderas genom loggrotation, så det är inte så ” garanterar dig inte hela systemets historik.

Ett förslag som visas några gånger (t.ex. den här tråden ) ska titta på katalogen /var/lib/dpkg/info. Filerna där föreslår att du kan prova något som:

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

För att svara på din fråga om val, här är ett första pass.

bygglista över paket efter datum

$ 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 

bygglista med installerade paket

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

gå med i de två listorna

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

Av någon anledning är det ” s skriver inte ut så många skillnader för mig, så det kan finnas ett fel eller ett ogiltigt antagande om vad --get-selections betyder.

Du kan självklart begränsa paketen antingen genom att använder find . -mtime -<days> eller head -n <lines> och ändrar utdataformatet som du vill, t.ex.

$ 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 

för att endast lista de val som har installerats (ändrats?) under de senaste fyra dagarna.

Du kan antagligen också ta bort kommandona sort efter att ha verifierat sorteringsordningen som används av dpkg --get-selections och gör find kommando mer effektivt.

Kommentarer

  • Jag gillar vanligtvis apt-get mer än rpm, men nu får debian -1 för att inte spara installationsdatumet i databasen. Debian-tricket innehåller alla installerade paket, inte bara de valda -paketen utan det ’ är en bra start.
  • För Debian få mindre cruft (tar bort half-installed poster) om du gör: grep install\ /var/log/dpkg.log
  • @Mikel – Bra svar. Jag utvidgade ’ samla /var/lib/dpkg/info/*.list filinformation ’ och lade till kod för att filtrera bort alla men ” toppnivåpaket ” (atp-paket som inga andra atp-paket är beroende av). Det < askubuntu.com/a/948532/723997> inlägg svarar på frågan ” Hur kan jag se historiken för apt-get installationskommandon som jag har utfört manuellt? ”.
  • Debian / Ubuntu: grep " install " /var/log/dpkg.log listar bara ”installera” -raderna istället för att också visa ”status”.
  • Om varken apt eller dpkg lagrar installation / modifierad datatid, verkar det ganska oacceptabelt för mig 2019. Vi litar på grepping loggfiler som kanske eller inte fortfarande finns på maskinen? Hur är så fallet?

Svar

Mikel har visat hur man gör detta på dpkg-nivå . I synnerhet skapas /var/lib/dpkg/info/$packagename.list när paketet installeras (och inte ändras efteråt).

Om du använde APT-verktygen (vilket du antagligen gjorde sedan du ” oroar sig automatiskt mot manuellt installerade paket), finns ”en historik i /var/log/apt/history.log. Så länge den inte har roterat bort håller den reda på alla APT-installationer, uppgraderingar och borttagningar, med en kommentar för paket som är markerade som automatiskt installerade. Detta är en ganska ny funktion, introducerad i APT 0.7.26, så i Debian dök upp i press. I Ubuntu, 10.04 har history.log men den automatiskt installerade anteckningen finns inte förrän 10.10.

Kommentarer

  • Som Mikel påpekade: ” Och så småningom kommer gamla /var/log/dpkg.log.*-filer att raderas genom loggrotation, så att det inte är ’ t garanterar att ge dig hela historiken för ditt system. ”. Se detta < askubuntu.com/a/948532/723997 > svar för hur man upptäcker de nuvarande toppnivåpaketen (vilket betyder de som inget annat paket beror på)

Svar

Grovt men fungerar:

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 

Kommentarer

  • Boo, viss för att analysera utdata från ls. Se mywiki.wooledge.org/ParsingLs för anteckningar om varför detta är farligt / i sig buggy – det säkrare alternativet är att använda antingen find -printf eller stat --format för att generera en ström som otvetydigt kan analyseras.
  • @CharlesDuffy Trevlig länk, men för enkelhetens skull, med ls -al --time-style=long-iso bör vara till hjälp. Dessutom är det förmodligen okänt att någon skulle namnge ett APT-paket med \n\t\r\v i sitt namn.

Svar

Här är one-liner som alla vill ha och behöver:

 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  

Resultatet visar alla (nyligen) installerade och uppgraderade paket i kronologisk ordning.

Radförklaringen:

  • ls -1t – få alla dpkg.log* filnamn i kronologisk ordning
  • zcat -f OM filen är av gzip typ, komprimera den sedan, ELSE överför bara innehållet.
  • tac – Omvänd utdata från cat , rad för rad för att se till att vi får rätt kronologisk ordning.
  • grep – Kontrollera endast för installerad eller uppgradera paket.
  • awk -F ":a" – Separera fältet arkitektur från paketnamnet
  • column -t – skriv ut kolumnerna separerade med mellanslag

Man skulle naturligtvis vilja skapa ett alias för detta, men tyvärr är det inte möjligt awk beror på både singel och dubbla citat. I det avseendet läggs det bäst i ett bash-skript och där : -avgränsaren hanteras bättre för andra arkitekturer i fältkolumnen.

Utgången är:

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 

Nackdel:

  • Som visas ovan fungerar det bara på ARM-arkitektur och behöver en liten modifiering för arkitekturfältavgränsaren
  • Behöver sättas in ett skript för enkelt alias
  • Har inte testats i andra * nix-system

Svar

Filen /var/log/apt/history.log har ett besvärligt format IMHO.

Startdatum: {date} {time } Kommandorad: {kommando} {alternativ …} Installera: {paket (version)}, …, {paket (version)}, … Slutdatum: {datum} {tid}

Jag skulle ha föredragit en mer loggfilformaterad post

{date} {time} {tab} {package} {tab} {version} {tab} {command} {options} \ n

eller någon XML som inte bara visar en { paket} men alla {beroenden}.

Som för närvarande implementerat, c en upptäcka informationen du söker men det kräver lite kriminalteknisk bearbetning för att extrahera detaljerna.

Svar

Detta fungerar för mig på en Debiansystem, jag antar att filformatet har ändrats sedan 2011. Detta system är ganska fräscht så jag skulle inte förvänta mig att det här skulle fungera på ett äldre system, även om det bara kan behöva packa upp loggarna och använda en glob för att referera till alla av dem.

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

De två första fälten i varje rad i filen /var/log/dpkg.log är datum och tid. Observera det efterföljande utrymmet med installation i grep-delen, detta beror på att uppgraderingar kan utlösa installationer men om jag förstod rätt ville du veta vad som installerades av användarna.

Kommentarer

  • Exakt vad jag gör. Lätt. Men du kan använda zgrep och alla dina .gz-loggar söks som zgrep ’ installera ’ /var/log/dpkg.log *.Placera mellanslag före ordet ” installera ” för att förhindra de irriterande ” halvinstallationer ”. Jag var tvungen att använda cut -f1,5 för att få fältets paketnamn. Naturligtvis roterar de gamla loggarna så småningom.

Svar

GNU / Linux Debian har inga inbyggda verktyg för detta problem, men all information om program installerade på standard sätt sparas i filer med programnamn. lista på platsen / var / lib / dpkg / info / . Men det finns ingen information om manuellt installerade program där.


En lång enradslösning :

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 

Förklaring :

  1. ls -rt matar ut filer sorterade efter datumändring i omvänd ordning, ie med de nyaste filerna i slutet av listan.
  2. stat skriver ut filen ”s datum i läsbar form.
  3. printf visar paketnamnet och datumet för dess senaste ändring.
  4. for loop som helhet skriver ut paketnamn och datum från äldsta till nyaste.

Utdataexempel (trunkerad):

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

Huvuddefekten i denna lösning är att den inte är väl testad i produkten ion.

Kommentarer

  • Detta är en vacker lösning som får jobbet nästan gjort. Det ’ är bara nackdelar, är att (1) det ’ är mycket långsamt och (2) att det bara visar när ett paket uppdaterades senast , inte någon av det ’ s tidigare versioner. Detta är naturligtvis inte ett problem med enfodret, men hur dpkg inte ’ inte håller reda på historiken i /var/lib/dpkg/info/. Det är också anledningen till att använda /var/log/dpkg.log*.

Svar

Noterar detta eftersom du nämner att andra distributionssvar är välkomna. rpm har en stor uppsättning utdataformattaggar, varav en är INSTALLTIME. (Med hjälp av wget)

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

Detta kan formateras på några sätt. Jag använder det på det här sättet:

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

Dessa två sidor har massor av bra information om att lösa problem med RPM-metadata:

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

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

Att sortera denna information skulle ge dig en fungerande lösning för ditt problem.

Svara

Det är grovt, men fungerar lika snabbt som andra lösningar. Datumformat är yyyymmddhhmmss, vilket innebär att en bit eller omordning och borttagning av format resulterar i ett nummer som kan sorteras.

Stort tack till de andra lösningarna, denna lista paketnamn i installationsordning som kan användas ett byggsystem för att kopiera operativsystem.

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}" 

Kommentarer

  • Välkommen @ alexander-cave! Lägg till några rader med output så att människor kan se vilken typ av output de kan förvänta sig.

Svar

Med roterade loggfiler i apt kan du:

zcat -f /var/log/dpkg.log* | grep " install " | less 

Svara

Jag har uppnått det på Kubuntu med följande kommandon:

  1. Lista upp paketen.
  2. läs varje standardinmatning.
  3. lagra hela sökväg (sökväg | skapat datum) med formatet ”% n |% y ” till en variabel.
  4. spara filnamnet i en variabel
  5. om båda tidigare kommandon utfördes framgångsrikt kommer värden att skrivas ut på en enda rad.
ls /var/lib/dpkg/info/*.list |while read xfile; do wpath=$(stat -c "%n|%y" ${xfile}) && wfile=$(basename ${xfile}) && printf "${wfile}|${wpath}\n" ;done 

Med vänliga hälsningar,

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *