Lista pakietów w systemie opartym na apt według daty instalacji

Jak wyświetlić listę zainstalowanych pakietów według daty instalacji?

Muszę to zrobić na debianie / ubuntu. Odpowiedzi na inne dystrybucje również byłyby fajne.

Zainstalowałem wiele rzeczy, aby skompilować pewien fragment kodu i chcę uzyskać listę pakietów, które musiałem zainstalować.

Komentarze

Odpowiedź

Dystrybucje oparte na RPM, takie jak Red Hat, są łatwe:

rpm -qa --last 

W Debianie i innych dystrybucjach opartych na dpkg twój specyficzny problem też jest łatwy:

grep install /var/log/dpkg.log 

O ile plik dziennika nie został obrócony, w takim przypadku należy spróbować:

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

Ogólnie rzecz biorąc, dpkg i apt nie wydają się śledzić daty instalacji ze względu na brak takiego pola w dpkg-query stronę podręcznika.

I ostatecznie stare /var/log/dpkg.log.* pliki zostaną usunięte przez rotację logów, więc nie jest to możliwe. Gwarantujemy, że podamy Ci całą historię Twojego systemu.

Jedna sugestia, która pojawi się kilka razy (np ten wątek ) ma na celu przejrzenie katalogu /var/lib/dpkg/info. Znajdujące się tam pliki sugerują, że możesz spróbować czegoś takiego:

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

Aby odpowiedzieć na pytanie dotyczące wyborów, oto pierwszy przebieg.

buduj listę pakietów według dat

$ 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 

buduj listę zainstalowanych pakietów

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

dołącz do 2 list

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

Z jakiegoś powodu to ” nie wypisuje dla mnie zbyt wielu różnic, więc może być błąd lub nieprawidłowe założenie dotyczące tego, co oznacza --get-selections.

Oczywiście możesz ograniczyć pakiety przez używając find . -mtime -<days> lub head -n <lines> i zmień format wyjściowy, jak chcesz, np.

$ 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 

, aby wyświetlić tylko te elementy, które zostały zainstalowane (zmienione?) w ciągu ostatnich 4 dni.

Prawdopodobnie możesz także usunąć polecenia sort po zweryfikowaniu kolejności sortowania używanej przez dpkg --get-selections i ustaw find wydajniejsze polecenie.

Komentarze

  • Zwykle podoba mi się apt-get bardziej niż rpm, ale teraz debian dostaje -1 za niezapisanie daty instalacji w bazie danych. Sztuczka Debiana obejmuje wszystkie zainstalowane pakiety, nie tylko wybrane , ale jest to ' dobry początek.
  • W przypadku Debiana uzyskaj mniej cruft (usuwa wpisy half-installed), jeśli to zrobisz: grep install\ /var/log/dpkg.log
  • @Mikel – Świetna odpowiedź. Rozszerzyłem ' zbieraj /var/lib/dpkg/info/*.list informacje o pliku ' i dodałem kod, aby odfiltrować wszystkie ale ” pakiety najwyższego poziomu ” (pakiety atp, od których nie zależą żadne inne pakiety atp). Ten < askubuntu.com/a/948532/723997> post odpowiada na pytanie ” Jak mogę wyświetlić historię poleceń apt-get install, które wykonałem ręcznie? „.
  • Debian / Ubuntu: grep " install " /var/log/dpkg.log wymienia tylko wiersze „instaluj”, a nie także „status”.
  • Jeśli ani apt, ani dpkg nie przechowują ani nie przechowują daty i godziny instalacji, wydaje mi się to nie do przyjęcia w 2019 roku. Polegaliśmy na grepowaniu plików dziennika, które mogą nadal znajdować się na komputerze lub nie? Jak to się dzieje?

Odpowiedź

Mikel pokazał, jak to zrobić na poziomie dpkg . W szczególności /var/lib/dpkg/info/$packagename.list jest tworzony, gdy pakiet jest instalowany (i nie jest później modyfikowany).

Jeśli używałeś narzędzi APT (co prawdopodobnie robiłeś od czasu ” martwimy się o pakiety instalowane automatycznie i ręcznie), w /var/log/apt/history.log jest historia. Dopóki się nie zmienił, śledzi wszystkie instalacje, aktualizacje i usunięcia APT, z adnotacjami dla pakietów oznaczonych jako instalowane automatycznie. Jest to dość nowa funkcja, wprowadzona w APT 0.7.26, więc w Debianie pojawił się w squeeze. W Ubuntu, 10.04 ma history.log, ale automatycznie zainstalowana adnotacja jest obecna dopiero 10.10.

Komentarze

  • Jak Mikel wskazał: ” I ostatecznie stare pliki /var/log/dpkg.log.* zostaną usunięte przez rotację logów, więc w ten sposób nie ' nie gwarantuje, że przekaże Ci całą historię Twojego systemu. „. Zobacz to < askubuntu.com/a/948532/723997 > odpowiedź, jak wykryć aktualne pakiety najwyższego poziomu (czyli takie, od których żaden inny pakiet nie zależy)

Odpowiedź

Szorstki, ale działa:

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 

Komentarze

  • Boo, syk, żeby przeanalizować wyjście z ls. Zobacz mywiki.wooledge.org/ParsingLs , aby dowiedzieć się, dlaczego jest to niebezpieczne / z natury wadliwe – bezpieczniejszą opcją jest użycie find -printf lub stat --format, aby wygenerować strumień, który można jednoznacznie przeanalizować.
  • @CharlesDuffy Ładny link, ale dla uproszczenia użyj ls -al --time-style=long-iso powinno być pomocne. Ponadto prawdopodobnie nie słyszano, aby ktoś nazwał pakiet APT z \n\t\r\v w nazwie.

Odpowiedź

Oto jedna linijka, której każdy chce i potrzebuje:

 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  

Wynik pokaże wszystkie (nowo) zainstalowane i zaktualizowane pakiety w porządku chronologicznym.

Objaśnienie wiersza:

  • ls -1t – pobierz wszystkie dpkg.log* nazwy plików w porządku chronologicznym
  • zcat -f IF plik jest typu gzip , a następnie rozpakuj go, ELSE po prostu przekaż treść.
  • tac – odwrotne wyjście cat , wiersz po wierszu, aby upewnić się, że otrzymujemy prawidłową kolejność chronologiczną.
  • grep – sprawdź tylko, czy są zainstalowane lub uaktualnij pakiety.
  • awk -F ":a" – Oddziel pole architektura od nazwy pakietu
  • column -t – ładnie wypisz kolumny oddzielone spacją

Oczywiście chciałoby się stworzyć alias, ale niestety nie jest to możliwe, ponieważ awk zależy zarówno od pojedynczego, jak i od podwójne cudzysłowy. W związku z tym najlepiej umieścić to w skrypcie basha i tam, gdzie separator : jest obsługiwany lepiej dla innych architektur w kolumnie pola.

Wynik:

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 

Wada:

  • Jak pokazano powyżej, działa tylko w architekturze ARM i wymaga niewielkiej modyfikacji separatora pól architektury
  • Należy umieścić w skrypt dla łatwego aliasu
  • Nie był testowany w innych systemach * nix

Odpowiedź

Plik /var/log/apt/history.log ma niezręczny format IMHO.

Data rozpoczęcia: {date} {godzina } Linia poleceń: {polecenie} {opcje …} Zainstaluj: {pakiet (wersja)}, …, {pakiet (wersja)}, … Data zakończenia: {data} {godzina}

Wolałbym rekord w formacie pliku dziennika.

{date} {time} {tab} {pakiet} {tab} {wersja} {tab} {command} {opcje} \ n

lub jakiś kod XML pokazujący nie tylko { pakiet}, ale wszelkie {zależności}.

Jak obecnie zaimplementowano, możesz c odkryć poszukiwane informacje, ale wyodrębnienie szczegółów wymaga pewnego przetwarzania kryminalistycznego.

Odpowiedź

To działa dla mnie na System Debian, domyślam się, że format pliku zmienił się od 2011 roku. Ten system jest całkiem świeży, więc nie spodziewałbym się, że zadziała na starszym systemie, chociaż może to wymagać tylko rozpakowania dzienników i użycia globu z nich.

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

Pierwsze dwa pola w każdym wierszu pliku /var/log/dpkg.log to data i godzina. Zwróć uwagę na końcową spację przy instalacji w części grep, ponieważ aktualizacje mogą powodować instalacje, ale jeśli dobrze zrozumiałem, chciałbyś wiedzieć, co zostało zainstalowane przez użytkowników.

Komentarze

  • Dokładnie to, co robię. Łatwo. Ale możesz użyć zgrep, a wszystkie twoje logi .gz zostaną przeszukane, np. Zgrep ' install ' /var/log/dpkg.log *.Umieść spację przed słowem ” zainstaluj „, aby zapobiec tym brzydkim ” połowicznym instalacjom „. Musiałem użyć cut -f1,5, aby uzyskać pole nazwy pakietu. Oczywiście w końcu stare logi są rotowane.

Odpowiedź

GNU / Linux Debian nie ma wbudowanych narzędzi w przypadku tego problemu, ale wszystkie informacje o programach zainstalowanych w standardowym sposobie są zapisywane w plikach z nazwa-programu. list w lokalizacji / var / lib / dpkg / info / . Ale nie ma tam żadnych informacji o programach zainstalowanych ręcznie.


Długie rozwiązanie jednowierszowe :

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 

Wyjaśnienie :

  1. ls -rt wyświetla pliki posortowane według modyfikacja daty w odwrotnej kolejności, tj. z najnowszymi plikami na końcu listy.
  2. stat wypisuje plik „s data w formie czytelnej dla człowieka.
  3. printf wyświetla nazwę pakietu i datę jej ostatniej modyfikacji.
  4. for jako całość wypisuje nazwy pakietów i daty od najstarszego do najnowszego.

Przykład wyników (obcięte):

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

Główną wadą tego rozwiązania jest to, że nie dobrze przetestowany w produkcie ion.

Komentarze

  • To piękne rozwiązanie, które prawie gotowe. Jego ' ma tylko wady, to to, że (1) działa ' bardzo wolno i (2) wyświetla się tylko wtedy, gdy pakiet był ostatnio aktualizowany , a nie żadna z jego wcześniejszych wersji '. Nie jest to oczywiście problem jednolinijkowy, ale sposób, w jaki dpkg nie ' nie śledzi historii w /var/lib/dpkg/info/. Dlatego też preferowane może być używanie /var/log/dpkg.log*.

Odpowiedź

Zauważając to, ponieważ wspomniałeś, że inne odpowiedzi dotyczące dystrybucji są mile widziane. rpm ma duży zestaw tagów formatu wyjściowego, z których jeden to CZAS INSTALACJI. (Na przykładzie wget)

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

Można to sformatować na kilka sposobów. Używam tego w ten sposób:

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

Te dwie strony zawierają mnóstwo świetnych informacji na temat rozwiązywania problemów z metadanymi RPM:

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

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

Posortowanie tych informacji zapewni działające rozwiązanie problemu.

Odpowiedź

To trudne, ale działa równie szybko jak inne rozwiązania. Format daty to rrrrmmddggmmss, co oznacza, że zmiana kolejności lub zmiana kolejności i usunięcie formatu skutkuje liczbą, którą można posortować.

Wielkie dzięki innym rozwiązaniom, ta lista zawiera nazwy pakietów w kolejności instalacji, które mogą być użyte w zbudowany do kopiowania systemu operacyjnego.

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

Komentarze

  • Witamy @ alexander-cave! Dodaj kilka wierszy danych wyjściowych , aby ludzie mogli zobaczyć, jakiego rodzaju wyników mogą się spodziewać.

Odpowiedź

Dzięki rotacyjnym plikom dziennika w apt można:

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

Odpowiedź

Osiągnąłem to na Kubuntu z następującymi poleceniami:

  1. Wyświetl listę pakietów.
  2. przeczytaj każde standardowe wejście.
  3. zapisz pełne ścieżka (ścieżka | data utworzenia) w formacie „% n |% y ” do zmiennej.
  4. zapisz nazwę pliku w zmiennej
  5. jeśli oba poprzednie polecenia zostały wykonane pomyślnie, wartości zostaną wydrukowane w jednej linii.
ls /var/lib/dpkg/info/*.list |while read xfile; do wpath=$(stat -c "%n|%y" ${xfile}) && wfile=$(basename ${xfile}) && printf "${wfile}|${wpath}\n" ;done 

Pozdrawiam,

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *