Liệt kê các gói trên hệ thống dựa trên apt theo ngày cài đặt


104

Làm thế nào tôi có thể liệt kê các gói cài đặt theo ngày cài đặt?

Tôi cần phải làm điều này trên debian / ubfox. Câu trả lời cho các bản phân phối khác cũng sẽ tốt đẹp.

Tôi đã cài đặt rất nhiều thứ để biên dịch một đoạn mã nhất định và tôi muốn có một danh sách các gói mà tôi phải cài đặt.



1
Tôi đã googling cho "ngày phát hành apt" không có may mắn, có thể nhận xét này sẽ giúp những người làm việc trong tương lai.
ThorSummoner

Câu trả lời:


66

Các bản phân phối dựa trên RPM như Red Hat rất dễ dàng:

rpm -qa --last

Trên Debian và các bản phân phối dựa trên dpkg khác, vấn đề cụ thể của bạn cũng rất dễ dàng:

grep install /var/log/dpkg.log

Trừ khi tệp nhật ký đã được xoay, trong trường hợp đó bạn nên thử:

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

Nói chung, dpkgaptdường như không theo dõi ngày cài đặt, do thiếu bất kỳ trường nào như vậy trong dpkg-querytrang man.

Và cuối cùng /var/log/dpkg.log.*các tệp cũ sẽ bị xóa bằng cách xoay vòng nhật ký, do đó cách đó không được đảm bảo để cung cấp cho bạn toàn bộ lịch sử hệ thống của bạn.

Một đề nghị xuất hiện một vài lần (ví dụ như chủ đề này ) là xem /var/lib/dpkg/infothư mục. Các tập tin ở đó gợi ý bạn có thể thử một cái gì đó như:

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

Để trả lời câu hỏi của bạn về các lựa chọn, đây là lần đầu tiên vượt qua.

xây dựng danh sách các gói theo ngày

$ 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

xây dựng danh sách các gói đã cài đặt

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

tham gia 2 danh sách

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

Vì một số lý do, nó không in ra nhiều sự khác biệt đối với tôi, vì vậy có thể có lỗi hoặc giả định không hợp lệ về ý --get-selectionsnghĩa của nó.

Rõ ràng bạn có thể giới hạn các gói bằng cách sử dụng find . -mtime -<days>hoặc head -n <lines>và thay đổi định dạng đầu ra như bạn muốn, ví dụ:

$ 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

để chỉ liệt kê các lựa chọn đã được cài đặt (thay đổi?) trong 4 ngày qua.

Bạn cũng có thể loại bỏ các sortlệnh sau khi xác minh thứ tự sắp xếp được sử dụng bởi dpkg --get-selectionsvà làm cho findlệnh hiệu quả hơn.


8
Tôi thường thích apt-getnhiều hơn rpm, nhưng bây giờ debian được -1 vì không lưu ngày cài đặt trong cơ sở dữ liệu. Thủ thuật debian bao gồm tất cả các gói đã cài đặt, không chỉ các gói đã chọn mà còn là một khởi đầu tốt.
Elazar Leibovich

Đối với Debian, bạn sẽ nhận được ít hành trình hơn (loại bỏ half-installedcác mục nhập) nếu bạn thực hiện:grep install\ /var/log/dpkg.log
Pierz

@Mikel - Câu trả lời tuyệt vời. Tôi đã mở rộng dựa trên 'tập hợp /var/lib/dpkg/info/*.list thông tin tệp' và thêm mã để lọc tất cả trừ "gói cấp cao nhất" (gói atp mà không có gói atp nào khác phụ thuộc). Đó là < askubfox.com/a/948532/723997 > post trả lời câu hỏi "Làm cách nào tôi có thể xem lịch sử của các lệnh cài đặt apt-get mà tôi đã thực hiện thủ công? ".
Craig Hicks

1
Debian / Ubuntu: grep " install " /var/log/dpkg.logchỉ liệt kê các dòng cài đặt của Wap chứ không chỉ hiển thị các dòng trạng thái của Google.
tráng miệng

Nếu cả apt và dpkg không lưu trữ cài đặt / sửa đổi datetime, điều đó dường như không thể chấp nhận được đối với tôi vào năm 2019. Chúng tôi đã dựa vào các tệp nhật ký có thể vẫn còn trên máy không? Làm thế nào là trường hợp này?
theferrit32

20

Mikel đã chỉ ra cách làm điều này ở cấp độ dpkg . Cụ thể, /var/lib/dpkg/info/$packagename.listđược tạo khi gói được cài đặt (và không được sửa đổi sau đó).

Nếu bạn đã sử dụng các công cụ APT (có lẽ bạn đã làm vì bạn lo ngại về việc tự động so với các gói được cài đặt thủ công), thì có một lịch sử /var/log/apt/history.log. Miễn là nó không bị quay đi, nó sẽ theo dõi tất cả các cài đặt, nâng cấp và gỡ bỏ APT, với chú thích cho các gói được đánh dấu là tự động cài đặt. Đây là một tính năng khá gần đây, được giới thiệu trong APT 0.7.26, vì vậy, trong Debian, nó xuất hiện dưới dạng nén. Trong Ubuntu, 10.04 có history.lognhưng chú thích được cài đặt tự động không xuất hiện cho đến 10.10.


1
Như Mikel đã chỉ ra: "Và cuối cùng, các tệp /var/log/dpkg.log.* cũ sẽ bị xóa bằng cách xoay vòng nhật ký, do đó cách đó không được đảm bảo để cung cấp cho bạn toàn bộ lịch sử hệ thống của bạn.". Xem câu hỏi < askubfox.com/a/948532/723997 > này để biết cách phát hiện các gói cấp cao nhất hiện tại (nghĩa là các gói không có gói nào khác phụ thuộc)
Craig Hicks

5

Rough, nhưng hoạt động:

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

2
Boo, rít cho phân tích đầu ra từ ls. Xem mywiki.wooledge.org/ParsingLs để biết các lý do tại sao điều này nguy hiểm / lỗi cố hữu - tùy chọn an toàn hơn là sử dụng find -printfhoặc stat --formatđể tạo một luồng có thể được phân tích cú pháp rõ ràng.
Charles Duffy

@CharlesDuffy Liên kết đẹp, nhưng với mục đích đơn giản, sử dụng ls -al --time-style=long-isonên hữu ích. Ngoài ra, có lẽ chưa từng thấy ai đó sẽ đặt tên cho gói APT với \n\t\r\vtên của nó.
not2qubit

4

Các /var/log/apt/history.logtập tin có một định dạng lúng túng IMHO.

Ngày bắt đầu: {ngày} {thời gian} Dòng lệnh: {lệnh} {tùy chọn ...} Cài đặt: {gói (phiên bản)}, ..., {gói (phiên bản)}, ... Ngày kết thúc: {ngày } {thời gian}

Tôi muốn có một bản ghi định dạng tệp nhật ký hơn

{ngày} {thời gian} {tab} {gói} {tab} {phiên bản} {tab} {lệnh} {tùy chọn} \ n

hoặc một số XML hiển thị không chỉ {gói} mà bất kỳ {phụ thuộc} nào.

Như hiện đang triển khai, bạn có thể khám phá thông tin bạn tìm kiếm nhưng nó yêu cầu một số xử lý pháp y để trích xuất các chi tiết.


3

Điều này hoạt động với tôi trên hệ thống Debian, tôi đoán định dạng tệp đã thay đổi kể từ năm 2011. Hệ thống này khá mới mẻ nên tôi không mong đợi nó hoạt động trên hệ thống cũ hơn, mặc dù điều đó có thể chỉ cần giải nén nhật ký và sử dụng một quả địa cầu để chỉ tất cả chúng.

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

Hai trường đầu tiên trong mỗi dòng của tệp /var/log/dpkg.loglà ngày và giờ. Lưu ý không gian dấu với cài đặt trong phần grep, điều này là do các bản nâng cấp có thể kích hoạt cài đặt nhưng nếu tôi hiểu chính xác, bạn muốn biết những gì đã được người dùng cài đặt.


1
Chính xác những gì tôi làm. Dễ dàng. Nhưng bạn có thể sử dụng zgrep và tất cả nhật ký .gz của bạn sẽ được tìm kiếm như zgrep 'install' /var/log/dpkg.log*. Đặt khoảng trắng trước từ "install" để ngăn những "nửa cài đặt" phiền phức đó. Tôi đã phải sử dụng cut -f1,5 để có được trường tên gói. Tất nhiên cuối cùng các bản ghi cũ xoay ra.
GeoO

2

Đây là một trong tất cả mọi người muốn và cần:

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

Kết quả sẽ hiển thị tất cả (mới) các gói được cài đặtnâng cấp theo thứ tự thời gian.

Dòng giải thích:

  • ls -1t- nhận tất cả các dpkg.log*tên tệp theo thứ tự thời gian
  • zcat -f- Tệp IF thuộc loại gzip sau đó giải nén nó, ELSE chỉ truyền vào nội dung.
  • tac- Đảo ngược đầu ra của mèo , từng dòng một để đảm bảo chúng ta có được thứ tự thời gian chính xác.
  • grep- Chỉ kiểm tra các gói cài đặt hoặc nâng cấp .
  • awk -F ':a'- Tách trường kiến trúc khỏi tên gói
  • column -t - in đẹp các cột cách nhau bởi không gian

Tất nhiên người ta muốn tạo một bí danh cho điều này, nhưng thật không may là không thể vì awk phụ thuộc vào cả dấu ngoặc đơn và dấu ngoặc kép. Về mặt này, tốt nhất là đưa vào một tập lệnh bash và trong đó :dấu phân cách được xử lý tốt hơn cho các kiến trúc khác trong cột trường.

Đầu ra là:

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

Hạn chế:

  • Như đã trình bày ở trên, nó chỉ hoạt động trên kiến ​​trúc ARM và cần sửa đổi một chút cho dấu tách trường kiến ​​trúc
  • Cần phải được đưa vào một kịch bản cho bí danh dễ dàng
  • Chưa được thử nghiệm trên các hệ thống * nix khác

1

Lưu ý điều này bởi vì bạn đề cập rằng các câu trả lời phân phối khác đều được chào đón. vòng / phút có một bộ thẻ định dạng đầu ra lớn, một trong số đó là INSTALLTIME. (Sử dụng wgetlàm ví dụ)

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

Điều này có thể được định dạng theo một vài cách. Tôi sử dụng nó theo cách này:

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

Hai trang này có rất nhiều thông tin tuyệt vời để giải quyết các vấn đề siêu dữ liệu RPM:

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

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

Sắp xếp thông tin này sẽ cung cấp cho bạn một giải pháp làm việc cho vấn đề của bạn.


1

GNU / Linux Debian không có công cụ tích hợp cho vấn đề này, nhưng tất cả thông tin về các chương trình được cài đặt theo cách tiêu chuẩn được lưu trong các tệp có chương trình-name.list trong vị trí / var / lib / dpkg / thông tin / . Nhưng không có thông tin về các chương trình cài đặt thủ công ở đó.


Một giải pháp đơn dòng dài :

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

Giải thích :

  1. ls -rtxuất các tệp được sắp xếp theo sửa đổi ngày theo thứ tự ngược lại, tức là với các tệp mới nhất ở cuối danh sách.
  2. stat in ngày của tập tin ở dạng người có thể đọc được.
  3. printf hiển thị tên gói và ngày sửa đổi cuối cùng của nó.
  4. Các forvòng lặp như một tên in trọn gói và số ngày từ cũ nhất đến mới nhất.

Ví dụ đầu ra (cắt ngắn):

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

Khiếm khuyết chính của giải pháp này. Đó là nó không được thử nghiệm tốt trong sản xuất.


Đây là một giải pháp đẹp mà hoàn thành công việc. Đó chỉ là nhược điểm, là (1) nó rất chậm và (2) nó chỉ hiển thị khi gói được cập nhật lần cuối , không phải bất kỳ phiên bản nào trước đó. Điều này, tất nhiên không phải là vấn đề của một-liner, nhưng làm thế nào dpkg không theo dõi lịch sử /var/lib/dpkg/info/. Đó cũng là lý do tại sao sử dụng /var/log/dpkg.log*có thể được ưa thích.
not2qubit

1

Đó là thô, nhưng hoạt động nhanh như các giải pháp khác. Định dạng ngày là yyyymmddhhmmss, có nghĩa là một chút hoặc sắp xếp lại và định dạng loại bỏ kết quả trong một số có thể được sắp xếp.

Rất cám ơn các giải pháp khác, danh sách gói tên này theo thứ tự cài đặt có thể được sử dụng trong một hệ điều hành được xây dựng để tạo bản sao.

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

Chào mừng @ alexander-cave! Vui lòng thêm một vài dòng đầu ra để mọi người có thể thấy loại đầu ra mong đợi.
not2qubit
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.