แสดงรายการแพ็กเกจบนระบบที่ใช้ apt ตามวันที่ติดตั้ง


104

ฉันจะแสดงรายการแพ็คเกจที่ติดตั้งภายในวันที่ติดตั้งได้อย่างไร

ฉันต้องทำสิ่งนี้บนเดเบียน / อูบุนตู คำตอบสำหรับการแจกแจงอื่น ๆ ก็ดีเช่นกัน

ฉันติดตั้งสิ่งต่าง ๆ จำนวนมากเพื่อรวบรวมรหัสบางส่วนและฉันต้องการได้รับรายการแพ็คเกจที่ฉันต้องติดตั้ง



1
ฉันใช้ Google เพื่อ "apt date date" โดยไม่มีโชคบางทีความคิดเห็นนี้อาจช่วยชาว Google ในอนาคตได้
ThorSummoner

คำถามที่คล้ายกันที่askubuntu.com "วิธีการแสดงรายการแพคเกจติดตั้งทั้งหมด"
JamesThomasMoon1979

คำตอบ:


66

การแจกแจงแบบ RPM เช่น Red Hat นั้นง่าย:

rpm -qa --last

ใน Debian และการแจกแจงแบบอิง dpkg อื่น ๆ ปัญหาเฉพาะของคุณก็ง่ายเช่นกัน:

grep install /var/log/dpkg.log

เว้นแต่ไฟล์บันทึกจะถูกหมุนในกรณีนี้คุณควรลอง:

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

โดยทั่วไปแล้วdpkgและaptดูเหมือนจะไม่ติดตามวันที่ติดตั้งโดยไม่มีฟิลด์ดังกล่าวในdpkg-queryหน้าเว็บมนุษย์

และในที่สุด/var/log/dpkg.log.*ไฟล์เก่าจะถูกลบโดยการหมุนบันทึกดังนั้นจึงไม่รับประกันว่าจะให้ประวัติทั้งหมดของระบบของคุณ

คำแนะนำหนึ่งที่ปรากฏขึ้นสองสามครั้ง (เช่นชุดข้อความนี้ ) คือดูที่/var/lib/dpkg/infoไดเรกทอรี ไฟล์ที่นั่นแนะนำให้คุณลองทำสิ่งต่อไปนี้:

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

เพื่อตอบคำถามของคุณเกี่ยวกับการเลือกนี่คือรอบแรก

สร้างรายการแพคเกจตามวันที่

$ 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

รายการสร้างของแพคเกจที่ติดตั้ง

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

เข้าร่วม 2 รายการ

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

ด้วยเหตุผลบางอย่างมันไม่ได้พิมพ์ความแตกต่างมากมายสำหรับฉันดังนั้นอาจมีข้อผิดพลาดหรือข้อสันนิษฐานที่ไม่ถูกต้องเกี่ยวกับความ--get-selectionsหมาย

คุณสามารถ จำกัด แพ็คเกจได้อย่างชัดเจนโดยใช้find . -mtime -<days>หรือhead -n <lines>เปลี่ยนรูปแบบเอาต์พุตตามที่คุณต้องการเช่น

$ 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

เพื่อแสดงรายการเฉพาะตัวเลือกที่ติดตั้ง (เปลี่ยน?) ใน 4 วันที่ผ่านมา

คุณอาจจะสามารถลบsortคำสั่งหลังจากตรวจสอบการเรียงลำดับที่ใช้โดยdpkg --get-selectionsและทำให้findคำสั่งมีประสิทธิภาพมากขึ้น


8
ฉันมักจะชอบapt-getมากกว่าrpmแต่ตอนนี้เดเบียนได้รับ -1 สำหรับไม่บันทึกวันที่ติดตั้งในฐานข้อมูล เคล็ดลับ debian รวมถึงแพ็คเกจที่ติดตั้งทั้งหมดไม่ใช่เฉพาะแพ็คเกจที่เลือกแต่เป็นการเริ่มต้นที่ดี
Elazar Leibovich

สำหรับ Debian คุณได้รับ cruft น้อย (เอาhalf-installedรายการ) ถ้าหากคุณ:grep install\ /var/log/dpkg.log
Pierz

@Mikel - คำตอบที่ดี ฉันขยายตาม 'รวบรวม /var/lib/dpkg/info/*.list ข้อมูลไฟล์' และเพิ่มรหัสเพื่อกรองออกทั้งหมดยกเว้น "แพ็คเกจระดับสูงสุด" (แพ็คเกจ atp ซึ่งไม่มีแพ็คเกจ atp อื่น ๆ ) < askubuntu.com/a/948532/723997 > โพสต์นั้นตอบคำถาม"ฉันจะดูประวัติของคำสั่งการติดตั้ง apt-get ที่ฉันได้ดำเนินการด้วยตนเองได้อย่างไร "
Craig Hicks

1
Debian / Ubuntu: grep " install " /var/log/dpkg.logแสดงเฉพาะบรรทัด "ติดตั้ง" แทนที่จะแสดง "สถานะ" เช่นกัน
ของหวาน

ถ้าไม่ใช่ทั้ง apt และ dpkg store ติดตั้ง / แก้ไข datetime นั่นดูเหมือนจะไม่เป็นที่ยอมรับในปี 2019 เราพึ่งพา grepping log files ซึ่งอาจอยู่ในเครื่องหรือไม่? กรณีนี้เป็นอย่างไร
theferrit32

20

มิเกลได้แสดงให้เห็นว่าการทำเช่นนี้ในระดับ dpkg โดยเฉพาะอย่างยิ่ง/var/lib/dpkg/info/$packagename.listจะถูกสร้างขึ้นเมื่อติดตั้งแพคเกจ (และไม่ได้แก้ไขภายหลัง)

ถ้าคุณใช้เครื่องมือ APT (ซึ่งคุณคงจะได้ตั้งแต่คุณกังวลเกี่ยวกับแพคเกจโดยอัตโนมัติด้วยตนเองเทียบกับการติดตั้ง) /var/log/apt/history.logมีความเป็นมาในประวัติศาสตร์ ตราบใดที่มันยังไม่หมุนมันจะติดตามการติดตั้ง APT ทั้งหมดอัปเกรดและลบออกพร้อมคำอธิบายประกอบสำหรับแพ็คเกจที่ทำเครื่องหมายว่าติดตั้งโดยอัตโนมัติ นี่เป็นคุณลักษณะล่าสุดที่นำมาใช้ใน APT 0.7.26 ดังนั้นใน Debian มันจึงปรากฏขึ้นในรูปแบบบีบ ใน Ubuntu มี 10.04 history.logแต่จะไม่มีคำอธิบายประกอบที่ติดตั้งโดยอัตโนมัติจนกว่าจะถึง 10.10


1
ดังที่ Mikel ชี้ให้เห็น: "และในที่สุดไฟล์เก่า /var/log/dpkg.log.* จะถูกลบโดยการหมุนบันทึกดังนั้นวิธีนี้จึงไม่รับประกันว่าจะให้ประวัติของระบบทั้งหมดของคุณ" ดูที่ < askubuntu.com/a/948532/723997 > คำตอบสำหรับวิธีการตรวจสอบแพ็คเกจระดับบนสุดในปัจจุบัน (หมายถึงแพ็คเกจที่ไม่มีแพ็คเกจอื่น)
Craig Hicks

5

หยาบ แต่ใช้ได้:

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
lsบูเย้ยหยันสำหรับการแยกเอาท์พุทจาก ดูmywiki.wooledge.org/ParsingLsเพื่อทราบว่าเหตุใดจึงเป็นอันตราย / บั๊กกี้ - ตัวเลือกที่ปลอดภัยกว่าคือการใช้อย่างใดอย่างหนึ่งfind -printfหรือstat --formatเพื่อสร้างกระแสที่สามารถแยกวิเคราะห์ได้อย่างไม่น่าสงสัย
ชาร์ลส์ดัฟฟี่

@CharlesDuffy Nice link แต่เพื่อความเรียบง่ายการใช้งานls -al --time-style=long-isoควรมีประโยชน์ นอกจากนี้อาจไม่เคยได้ยินว่ามีใครบางคนจะตั้งชื่อแพ็คเกจ APT ด้วย\n\t\r\vในชื่อของมัน
not2qubit

4

/var/log/apt/history.logไฟล์มีรูปแบบที่น่าอึดอัดใจ IMHO

วันที่เริ่มต้น: {date} {เวลา} Commandline: {command} {options ... } ติดตั้ง: {package (version)}, ... , {package (version)}, ... End-Date: {date } {เวลา}

ฉันต้องการบันทึกการจัดรูปแบบไฟล์บันทึกเพิ่มเติม

วันที่ {date} {เวลา} {} {แท็บแพคเกจ} {} {แท็บรุ่นแท็บ} {} {} {คำสั่งตัวเลือก} \ n

หรือบาง XML แสดงไม่เพียง {package} แต่ {dependencies} ใด ๆ

ตามที่ได้ดำเนินการแล้วในปัจจุบันคุณสามารถค้นพบข้อมูลที่คุณต้องการ แต่ต้องใช้กระบวนการทางนิติวิทยาศาสตร์เพื่อแยกรายละเอียด


3

สิ่งนี้ใช้ได้กับฉันในระบบ Debian ฉันคาดว่ารูปแบบไฟล์จะเปลี่ยนไปตั้งแต่ปี 2011 ระบบนี้ค่อนข้างใหม่ดังนั้นฉันจึงไม่คาดหวังว่านี่จะทำงานกับระบบเก่าแม้ว่ามันอาจต้องใช้การคลายไฟล์บันทึก กลมเพื่ออ้างถึงพวกเขาทั้งหมด

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

สองฟิลด์แรกในแต่ละบรรทัดของไฟล์/var/log/dpkg.logคือวันที่และเวลา โปรดสังเกตว่าพื้นที่ต่อท้ายพร้อมกับการติดตั้งในส่วน grep นี้เป็นเพราะการอัพเกรดสามารถทริกเกอร์การติดตั้ง แต่ถ้าฉันเข้าใจอย่างถูกต้องคุณต้องการที่จะรู้ว่าสิ่งที่ถูกติดตั้งโดยผู้ใช้


1
สิ่งที่ฉันทำ ง่าย. แต่คุณสามารถใช้ zgrep และบันทึก. gz ทั้งหมดของคุณจะได้รับการค้นหาเช่น zgrep 'install' /var/log/dpkg.log* วางช่องว่างไว้ข้างคำว่า "ติดตั้ง" เพื่อป้องกันการติดตั้ง "ครึ่ง" ที่น่ารำคาญ ฉันต้องใช้ cut-f1,5 เพื่อรับฟิลด์ชื่อแพ็คเกจ แน่นอนที่สุดบันทึกเก่าจะถูกหมุนเวียน
geoO

2

นี่คือหนึ่งซับที่ทุกคนต้องการและต้องการ:

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

ผลลัพธ์จะแสดงแพคเกจที่เพิ่งติดตั้งและอัปเกรดทั้งหมดตามลำดับเวลา

คำอธิบายบรรทัด:

  • ls -1t- รับdpkg.log*ชื่อไฟล์ทั้งหมดตามลำดับเวลา
  • zcat -f- หากไฟล์นั้นเป็นประเภทgzipจากนั้นคลายการบีบอัดไฟล์ELSEเพียงส่งเนื้อหา
  • tac- เอาท์พุทย้อนกลับของแมวบรรทัดต่อบรรทัดเพื่อให้แน่ใจว่าเราได้รับคำสั่งตามลำดับเวลาที่ถูกต้อง
  • grep- ตรวจสอบแพ็คเกจที่ติดตั้งหรืออัพเกรดเท่านั้น
  • awk -F ':a'- แยกฟิลด์สถาปัตยกรรมออกจากชื่อแพ็คเกจ
  • column -t - พิมพ์สวยคอลัมน์คั่นด้วยช่องว่าง

แน่นอนว่าเราต้องการสร้างนามแฝงสำหรับสิ่งนี้ แต่น่าเสียดายที่ไม่สามารถทำได้เนื่องจากawkขึ้นอยู่กับคำพูดเดี่ยวและคู่ ในเรื่องนี้ควรใส่ไว้ในสคริปต์ทุบตีที่ดีที่สุดและตำแหน่ง:ตัวจัดการถูกจัดการได้ดีกว่าสำหรับสถาปัตยกรรมอื่น ๆในคอลัมน์เขตข้อมูล

ผลลัพธ์คือ:

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

ข้อเสียเปรียบ:

  • ดังที่แสดงไว้ด้านบนใช้งานได้กับสถาปัตยกรรม ARM และต้องการการปรับเปลี่ยนเล็กน้อยสำหรับตัวคั่นฟิลด์สถาปัตยกรรม
  • จำเป็นต้องใส่สคริปต์เพื่อให้นามแฝงง่าย
  • ไม่ได้รับการทดสอบในระบบ * nix อื่น ๆ

1

สังเกตสิ่งนี้เพราะคุณพูดถึงว่ามีคำตอบการกระจายอื่น ๆ ยินดีต้อนรับ รอบต่อนาทีมีแท็กรูปแบบเอาต์พุตจำนวนมากโดยหนึ่งในนั้นคือ INSTALLTIME (ใช้wgetเป็นตัวอย่าง)

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

สามารถฟอร์แมตได้สองสามวิธี ฉันใช้วิธีนี้:

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

สองหน้านี้มีข้อมูลที่ยอดเยี่ยมเกี่ยวกับการแก้ไขปัญหาเมตาดาต้า RPM:

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

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

การเรียงลำดับข้อมูลนี้จะช่วยให้คุณแก้ไขปัญหาได้


1

GNU / Linux Debian ไม่มีเครื่องมือในตัวสำหรับปัญหานี้ แต่ข้อมูลทั้งหมดที่เกี่ยวกับโปรแกรมที่ติดตั้งในวิธีมาตรฐานจะถูกบันทึกในไฟล์ที่มีโปรแกรม name.listในสถานที่/ var / lib / dpkg / ข้อมูล / แต่ไม่มีข้อมูลเกี่ยวกับโปรแกรมที่ติดตั้งด้วยตนเองที่นั่น


โซลูชันบรรทัดเดียวที่มีความยาว :

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

คำอธิบาย :

  1. ls -rtไฟล์ที่ส่งออกเรียงลำดับตามการปรับเปลี่ยนวันที่ในลำดับย้อนกลับคือกับไฟล์ใหม่ล่าสุดในตอนท้ายของรายการ
  2. stat พิมพ์วันที่ของไฟล์ในรูปแบบที่มนุษย์สามารถอ่านได้
  3. printf แสดงชื่อแพ็คเกจและวันที่แก้ไขล่าสุด
  4. การforวนซ้ำโดยรวมจะพิมพ์ชื่อแพ็กเกจและวันที่จากเก่าไปใหม่

ตัวอย่างผลลัพธ์ (ตัด):

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

ข้อบกพร่องหลักของการแก้ปัญหานี้คือมันไม่ได้ผ่านการทดสอบอย่างดีในการผลิต


นี่เป็นทางออกที่สวยงามที่ทำให้งานเกือบเสร็จสิ้น ข้อเสียเปรียบเพียงอย่างเดียวคือ (1) ช้ามากและ (2) จะแสดงเฉพาะเมื่อมีการอัปเดตแพคเกจครั้งล่าสุดไม่ใช่เวอร์ชันก่อนหน้าใด ๆ แน่นอนว่านี่ไม่ใช่ปัญหาของสายการบินเดียว แต่วิธีการที่ dpkg ไม่สามารถติดตามประวัติ/var/lib/dpkg/info/ได้ นั่นคือเหตุผลที่/var/log/dpkg.log*อาจจะต้องการการใช้งาน
not2qubit

1

มันหยาบ แต่ทำงานได้เร็วเท่ากับวิธีแก้ปัญหาอื่น ๆ รูปแบบวันที่คือ yyyymmddhhmmss ซึ่งหมายความว่าบิตหรือการเรียงลำดับใหม่และผลลัพธ์การลบรูปแบบในจำนวนที่สามารถเรียงลำดับ

ขอบคุณมากกับโซลูชั่นอื่น ๆ ชื่อแพคเกจรายการนี้ตามลำดับการติดตั้งที่สามารถใช้ในตัวเพื่อสร้างระบบปฏิบัติการคัดลอก

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

ยินดีต้อนรับ @ alexander- ถ้ำ! โปรดเพิ่มเอาต์พุตสองสามบรรทัดเพื่อให้ผู้คนสามารถเห็นผลลัพธ์ที่คาดหวัง
not2qubit
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.