Lijst met pakketten op een op apt gebaseerd systeem op installatiedatum

Hoe kan ik geïnstalleerde pakketten op installatiedatum weergeven?

Ik moet dit doen op debian / ubuntu. Antwoorden voor andere distributies zouden ook leuk zijn.

Ik heb veel dingen geïnstalleerd om een bepaald stuk code te compileren, en ik wil een lijst krijgen van de pakketten die ik moest installeren.

Reacties

Answer

RPM-gebaseerde distributies zoals Red Hat zijn eenvoudig:

rpm -qa --last 

Op Debian en andere op dpkg gebaseerde distributies is uw specifieke probleem ook gemakkelijk:

grep install /var/log/dpkg.log 

Tenzij het logbestand is geroteerd, probeer in dat geval:

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

In het algemeen lijken dpkg en apt de installatiedatum niet bij te houden, aangezien een dergelijk veld in de dpkg-query man-pagina.

En uiteindelijk zullen oude /var/log/dpkg.log.* bestanden worden verwijderd door logboekrotatie, dus op die manier is het niet ” t geeft u gegarandeerd de volledige geschiedenis van uw systeem.

Een suggestie die een paar keer verschijnt (bijv deze thread ) moet naar de /var/lib/dpkg/info -directory kijken. De bestanden daar suggereren dat je iets zou kunnen proberen als:

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

Om je vraag over selecties te beantwoorden, hier “een eerste poging.

lijst met pakketten op 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 

lijst met geïnstalleerde pakketten

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

word lid van de 2 lijsten

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

Om de een of andere reden is het ” s drukt voor mij niet veel verschillen af, dus er kan een bug zijn of een ongeldige aanname over wat --get-selections betekent.

U kunt de pakketten uiteraard beperken door gebruik find . -mtime -<days> of head -n <lines>, en verander het uitvoerformaat zoals je wilt, bijv.

$ 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 

om alleen de selecties weer te geven die in de afgelopen 4 dagen zijn geïnstalleerd (gewijzigd?).

U kunt waarschijnlijk ook de sort -opdrachten verwijderen na verificatie van de sorteervolgorde gebruikt door dpkg --get-selections en maak de find commando efficiënter.

Reacties

  • Ik vind apt-get meestal leuker dan rpm, maar nu krijgt debian -1 voor het niet opslaan van de installatiedatum in de database. De debian-truc omvat alle geïnstalleerde pakketten, niet alleen de geselecteerde pakketten, maar het is ‘ een goed begin.
  • Voor Debian u krijg minder cruft (verwijdert half-installed items) als je dat doet: grep install\ /var/log/dpkg.log
  • @Mikel – Goed antwoord. Ik heb de ‘ gather /var/lib/dpkg/info/*.list bestandsinfo ‘ uitgebreid en code toegevoegd om alles eruit te filteren maar de ” pakketten op het hoogste niveau ” (atp-pakketten waarvan geen andere atp-pakketten afhankelijk zijn). Dat < askubuntu.com/a/948532/723997> post beantwoordt de vraag ” Hoe kan ik de geschiedenis bekijken van apt-get installatieopdrachten die ik handmatig heb uitgevoerd? “.
  • Debian / Ubuntu: grep " install " /var/log/dpkg.log geeft alleen de “install” -regels weer in plaats van ook de “status” -regels weer te geven.
  • Als apt noch dpkg datetime installeert / wijzigt, lijkt me dat in 2019 behoorlijk onaanvaardbaar. We vertrouwen op grepping-logbestanden die al dan niet nog op de machine staan? Hoe is dit het geval?

Antwoord

Mikel heeft laten zien hoe je dit kunt doen op het dpkg-niveau . In het bijzonder wordt /var/lib/dpkg/info/$packagename.list gemaakt wanneer het pakket wordt geïnstalleerd (en daarna niet gewijzigd).

Als u de APT-tools gebruikte (wat u vermoedelijk deed sinds u ” bezorgd over automatisch versus handmatig geïnstalleerde pakketten), is er “een geschiedenis in /var/log/apt/history.log. Zolang het niet is weggeroteerd, houdt het alle APT-installaties, upgrades en verwijderingen bij, met een annotatie voor pakketten die zijn gemarkeerd als automatisch geïnstalleerd. Dit is een vrij recente functie, geïntroduceerd in APT 0.7.26, dus in Debian verscheen in squeeze. In Ubuntu, 10.04 heeft history.log maar de automatisch geïnstalleerde annotatie is pas aanwezig op 10.10.

Opmerkingen

  • Zoals Mikel wees erop: ” En uiteindelijk zullen oude /var/log/dpkg.log.* bestanden worden verwijderd door logboekrotatie, dus op die manier is niet ‘ t geeft u gegarandeerd de volledige geschiedenis van uw systeem. “. Zie dit < askubuntu.com/a/948532/723997 > antwoord voor het detecteren van de huidige pakketten op het hoogste niveau (dwz degene waarvan geen ander pakket afhankelijk is)

Antwoord

Ruw, maar werkt:

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 

Reacties

  • Boe, gesis voor het parseren van uitvoer van ls. Zie mywiki.wooledge.org/ParsingLs voor opmerkingen over waarom dit gevaarlijk / inherent buggy is – de veiligere optie is om ofwel of stat --format om een stream te genereren die ondubbelzinnig kan worden geparseerd.
  • @CharlesDuffy Leuke link, maar voor de eenvoud, gebruik ls -al --time-style=long-iso zou nuttig moeten zijn. Bovendien is het waarschijnlijk ongehoord dat iemand een APT-pakket een naam zou geven met \n\t\r\v in zijn naam.

Antwoord

Hier is de one-liner die iedereen wil en nodig heeft:

 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  

Het resultaat toont alle (nieuw) geïnstalleerde en opgewaardeerde pakketten in chronologische volgorde.

De regeluitleg:

  • ls -1t – haal alle dpkg.log* bestandsnamen op in chronologische volgorde
  • zcat -f ALS bestand van het type gzip is, pak het dan uit, ELSE geef gewoon de inhoud door.
  • tac – Omgekeerde uitvoer van kat , regel voor regel om er zeker van te zijn dat we de juiste chronologische volgorde krijgen.
  • grep – Controleer alleen of geïnstalleerd of upgrade pakketten.
  • awk -F ":a" – Scheid het veld architectuur van de pakketnaam
  • column -t – druk de kolommen mooi af, gescheiden door een spatie.

Je zou hier natuurlijk graag een alias voor willen maken, maar dat is helaas niet mogelijk omdat awk is afhankelijk van zowel single als dubbele aanhalingstekens. In dat opzicht kan dit het beste in een bash-script worden gestopt en waar het : scheidingsteken beter wordt afgehandeld voor andere architecturen in de veldkolom.

De uitvoer is:

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 

Nadeel:

  • Zoals hierboven getoond, werkt het alleen op ARM-architectuur en heeft het een kleine aanpassing nodig voor de architectuurveldscheidingsteken
  • Moet in een script voor eenvoudige alias
  • Is niet getest in andere * nix-systemen

Antwoord

Het /var/log/apt/history.log -bestand heeft een onhandig IMHO-formaat.

Startdatum: {date} {time } Commandoregel: {command} {opties …} Installeren: {pakket (versie)}, …, {pakket (versie)}, … Einddatum: {datum} {tijd}

Ik had liever een record in logboekformaat gehad

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

of een XML die niet alleen een { package} maar alle {afhankelijkheden}.

Zoals momenteel geïmplementeerd, c en ontdek de informatie die u zoekt, maar het vereist enige forensische verwerking om de details te extraheren.

Answer

Dit werkt voor mij op een Debian-systeem, ik vermoed dat het bestandsformaat is veranderd sinds 2011. Dit systeem is behoorlijk vers, dus ik zou niet verwachten dat dit werkt op een ouder systeem, hoewel dat misschien gewoon de logboeken moet uitpakken en een glob moet gebruiken om naar alle van hen.

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

De eerste twee velden in elke regel van het bestand /var/log/dpkg.log zijn de datum en tijd. Let op de volgruimte met installatie in het grep-gedeelte, dit komt omdat upgrades installaties kunnen activeren, maar als ik het goed heb begrepen, wilde je weten wat er door gebruikers is geïnstalleerd.

Opmerkingen

  • Precies wat ik doe. Gemakkelijk. Maar je kunt zgrep gebruiken en al je .gz-logboeken worden doorzocht zoals zgrep ‘ install ‘ /var/log/dpkg.log *.Plaats de spatie voor het woord ” install ” om die vervelende ” halve installaties te voorkomen “. Ik moest cut -f1,5 gebruiken om het pakketnaamveld te krijgen. Natuurlijk worden de oude logboeken uiteindelijk verwijderd.

Antwoord

GNU / Linux Debian heeft geen ingebouwde tools voor dit probleem, maar alle informatie over programmas die zijn geïnstalleerd in de standaardmanier wordt opgeslagen in bestanden met programmanaam. list op de locatie / var / lib / dpkg / info / . Maar er is daar geen informatie over handmatig geïnstalleerde programmas.


Een lange oplossing met één regel :

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 

Uitleg :

  1. ls -rt voert bestanden uit gesorteerd op datumwijziging in omgekeerde volgorde, dwz met de nieuwste bestanden aan het einde van de lijst.
  2. stat drukt de bestanden af datum in voor mensen leesbare vorm.
  3. printf toont de pakketnaam en de datum van de laatste wijziging.
  4. De for lus als geheel drukt pakketnamen en datums af van oudste naar nieuwste.

Uitvoervoorbeeld (afgekapt):

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

Het belangrijkste defect van deze oplossing is dat het niet goed getest in product ion.

Opmerkingen

  • Dit is een prachtige oplossing waarmee de klus bijna geklaard is. Het ‘ s enige nadelen, zijn dat (1) het ‘ erg langzaam is en (2) dat het alleen wordt weergegeven wanneer een pakket is voor het laatst bijgewerkt , niet een van de ‘ s vorige versies. Dit is natuurlijk geen probleem van de one-liner, maar hoe dpkg de geschiedenis niet ‘ bijhoudt in /var/lib/dpkg/info/. Dat is ook de reden waarom het gebruik van /var/log/dpkg.log* de voorkeur kan hebben.

Antwoord

Dit opmerken omdat u vermeldt dat andere distributie-antwoorden welkom zijn. rpm heeft een grote set output formaat tags, waarvan er één INSTALLTIME is. (Met wget als voorbeeld)

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

Dit kan op een aantal manieren worden opgemaakt. Ik gebruik het op deze manier:

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

Deze twee paginas bevatten een hoop geweldige informatie over het oplossen van problemen met 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

Door deze informatie te sorteren, zou u een werkende oplossing voor uw probleem hebben.

Antwoord

Het is ruw, maar werkt net zo snel als andere oplossingen. Datumnotatie is jjjjmmdduummss, wat betekent dat een bit of herschikken en verwijderen van formaat resulteert in een nummer dat kan worden gesorteerd.

Veel dank aan de andere oplossingen, deze lijst met pakketnamen in volgorde van installatie die kunnen worden gebruikt in een gebouwd om kopieerbesturingssysteem te maken.

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

Reacties

  • Welkom @ alexander-cave! Voeg een paar regels output toe zodat mensen kunnen zien wat voor soort output ze kunnen verwachten.

Antwoord

Met geroteerde logfiles in apt kunt u:

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

Answer

Ik heb het bereikt op Kubuntu met de volgende opdrachten:

  1. Maak een lijst van de pakketten.
  2. lees elke standaardinvoer.
  3. sla de volledige pad (pad | aangemaakte datum) met de indeling “% n |% y ” in een variabele.
  4. sla de naam van het bestand op in een variabele.
  5. als beide vorige opdrachten met succes zijn uitgevoerd, worden de waarden op één regel afgedrukt.
ls /var/lib/dpkg/info/*.list |while read xfile; do wpath=$(stat -c "%n|%y" ${xfile}) && wfile=$(basename ${xfile}) && printf "${wfile}|${wpath}\n" ;done 

Met vriendelijke groet,

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *