it-swarm-vi.com

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

Làm cách 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ẽ rất hay.

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.

106
Elazar Leibovich

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, dpkgapt dườ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-query trang nam.

Và cuối cùng là già /var/log/dpkg.log.* các tệp 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 đề xuất xuất hiện một vài lần (ví dụ chủ đề này ) là xem xét /var/lib/dpkg/info danh 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ề những gì --get-selections có nghĩa.

Bạn rõ ràng có thể giới hạn các gói bằng cách sử dụng find . -mtime -<days> hoặc là 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ể xóa các lệnh sort sau khi xác minh thứ tự sắp xếp được sử dụng bởi dpkg --get-selections và làm cho lệnh find hiệu quả hơn.

68
Mikel

Mikel đã chỉ ra cách làm điều này ở cấp độ dpkg . Đặc biệt, /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 (mà bạn có lẽ đã làm vì bạn lo ngại về các gói được cài đặt thủ công), sẽ có một lịch sử trong /var/log/apt/history.log. Miễn là nó không bị quay đi, nó sẽ theo dõi tất cả APT cài đặt, nâng cấp và xóa, 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.log nhưng chú thích được cài đặt tự động không xuất hiện cho đến ngày 10.10.

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
6
Dulantha

Các /var/log/apt/history.log tập tin có đị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.

4
Saint DanBert

Đ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 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.log là ngày và thời gian. 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.

3
Amias

Đâ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ả các gói (mới) đã cài đặt đã nâng cấp theo thời gian đặt hàng.

Giải thích dòng :

  • ls -1t - lấy tất cả dpkg.log* tên tệp theo thứ tự thời gian
  • zcat -f - NẾU tệp thuộc loại gzip sau đó giải nén nó, - OTHER chỉ truyền vào nội dung.
  • tac - Đầu ra ngược của cat , từng dòng một để đảm bảo chúng tôi 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 gói .
  • 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 khoảng trắng

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ề vấn đề này, tốt nhất là đưa vào tập lệnh bash và trong đó : separator đượ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

Nhược điểm :

  • Như được hiển thị ở 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
2
not2qubit

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 trong cách chuẩn được lưu trong các tệp có chương trình-name.list ở vị trí /var/lib/dpkg/thông tin/. Nhưng không có thông tin về các chương trình được cài đặt thủ công ở đó.


Một giải pháp một 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 -rt xuấ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 ở 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. Vòng lặp for dưới dạng toàn bộ in tên gói và 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.

1
PADYMKO

Đó 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}'
1
Alexander Cave

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 wget là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
Jonathan Swift