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
- Zobacz także Jak uzyskać historię instalacji apt-get .
- Wyszukałem w Google ” datę wydania apt ” bez powodzenia, może ten komentarz pomoże przyszłym pracownikom Google.
- Podobne pytanie pod adresem askubuntu.com ” Jak wyświetlić listę wszystkich zainstalowanych pakietów ” .
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życiefind -printf
lubstat --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 wszystkiedpkg.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 :
-
ls -rt
wyświetla pliki posortowane według modyfikacja daty w odwrotnej kolejności, tj. z najnowszymi plikami na końcu listy. -
stat
wypisuje plik „s data w formie czytelnej dla człowieka. -
printf
wyświetla nazwę pakietu i datę jej ostatniej modyfikacji. -
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:
- Wyświetl listę pakietów.
- przeczytaj każde standardowe wejście.
- zapisz pełne ścieżka (ścieżka | data utworzenia) w formacie „% n |% y ” do zmiennej.
- zapisz nazwę pliku w zmiennej
- 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,