ฉันจะแสดงรายการแพ็คเกจที่ติดตั้งภายในวันที่ติดตั้งได้อย่างไร
ฉันต้องทำสิ่งนี้บนเดเบียน / อูบุนตู คำตอบสำหรับการแจกแจงอื่น ๆ ก็ดีเช่นกัน
ฉันติดตั้งสิ่งต่าง ๆ จำนวนมากเพื่อรวบรวมรหัสบางส่วนและฉันต้องการได้รับรายการแพ็คเกจที่ฉันต้องติดตั้ง
ฉันจะแสดงรายการแพ็คเกจที่ติดตั้งภายในวันที่ติดตั้งได้อย่างไร
ฉันต้องทำสิ่งนี้บนเดเบียน / อูบุนตู คำตอบสำหรับการแจกแจงอื่น ๆ ก็ดีเช่นกัน
ฉันติดตั้งสิ่งต่าง ๆ จำนวนมากเพื่อรวบรวมรหัสบางส่วนและฉันต้องการได้รับรายการแพ็คเกจที่ฉันต้องติดตั้ง
คำตอบ:
การแจกแจงแบบ 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
คำสั่งมีประสิทธิภาพมากขึ้น
apt-get
มากกว่าrpm
แต่ตอนนี้เดเบียนได้รับ -1 สำหรับไม่บันทึกวันที่ติดตั้งในฐานข้อมูล เคล็ดลับ debian รวมถึงแพ็คเกจที่ติดตั้งทั้งหมดไม่ใช่เฉพาะแพ็คเกจที่เลือกแต่เป็นการเริ่มต้นที่ดี
half-installed
รายการ) ถ้าหากคุณ:grep install\ /var/log/dpkg.log
grep " install " /var/log/dpkg.log
แสดงเฉพาะบรรทัด "ติดตั้ง" แทนที่จะแสดง "สถานะ" เช่นกัน
มิเกลได้แสดงให้เห็นว่าการทำเช่นนี้ในระดับ 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
หยาบ แต่ใช้ได้:
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
ls
บูเย้ยหยันสำหรับการแยกเอาท์พุทจาก ดูmywiki.wooledge.org/ParsingLsเพื่อทราบว่าเหตุใดจึงเป็นอันตราย / บั๊กกี้ - ตัวเลือกที่ปลอดภัยกว่าคือการใช้อย่างใดอย่างหนึ่งfind -printf
หรือstat --format
เพื่อสร้างกระแสที่สามารถแยกวิเคราะห์ได้อย่างไม่น่าสงสัย
ls -al --time-style=long-iso
ควรมีประโยชน์ นอกจากนี้อาจไม่เคยได้ยินว่ามีใครบางคนจะตั้งชื่อแพ็คเกจ APT ด้วย\n\t\r\v
ในชื่อของมัน
/var/log/apt/history.log
ไฟล์มีรูปแบบที่น่าอึดอัดใจ IMHO
วันที่เริ่มต้น: {date} {เวลา} Commandline: {command} {options ... } ติดตั้ง: {package (version)}, ... , {package (version)}, ... End-Date: {date } {เวลา}
ฉันต้องการบันทึกการจัดรูปแบบไฟล์บันทึกเพิ่มเติม
วันที่ {date} {เวลา} {} {แท็บแพคเกจ} {} {แท็บรุ่นแท็บ} {} {} {คำสั่งตัวเลือก} \ n
หรือบาง XML แสดงไม่เพียง {package} แต่ {dependencies} ใด ๆ
ตามที่ได้ดำเนินการแล้วในปัจจุบันคุณสามารถค้นพบข้อมูลที่คุณต้องการ แต่ต้องใช้กระบวนการทางนิติวิทยาศาสตร์เพื่อแยกรายละเอียด
สิ่งนี้ใช้ได้กับฉันในระบบ Debian ฉันคาดว่ารูปแบบไฟล์จะเปลี่ยนไปตั้งแต่ปี 2011 ระบบนี้ค่อนข้างใหม่ดังนั้นฉันจึงไม่คาดหวังว่านี่จะทำงานกับระบบเก่าแม้ว่ามันอาจต้องใช้การคลายไฟล์บันทึก กลมเพื่ออ้างถึงพวกเขาทั้งหมด
grep 'install ' /var/log/dpkg.log.1 | sort | cut -f1,2,4 -d' '
สองฟิลด์แรกในแต่ละบรรทัดของไฟล์/var/log/dpkg.log
คือวันที่และเวลา โปรดสังเกตว่าพื้นที่ต่อท้ายพร้อมกับการติดตั้งในส่วน grep นี้เป็นเพราะการอัพเกรดสามารถทริกเกอร์การติดตั้ง แต่ถ้าฉันเข้าใจอย่างถูกต้องคุณต้องการที่จะรู้ว่าสิ่งที่ถูกติดตั้งโดยผู้ใช้
นี่คือหนึ่งซับที่ทุกคนต้องการและต้องการ:
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
ข้อเสียเปรียบ:
สังเกตสิ่งนี้เพราะคุณพูดถึงว่ามีคำตอบการกระจายอื่น ๆ ยินดีต้อนรับ รอบต่อนาทีมีแท็กรูปแบบเอาต์พุตจำนวนมากโดยหนึ่งในนั้นคือ 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
การเรียงลำดับข้อมูลนี้จะช่วยให้คุณแก้ไขปัญหาได้
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
คำอธิบาย :
ls -rt
ไฟล์ที่ส่งออกเรียงลำดับตามการปรับเปลี่ยนวันที่ในลำดับย้อนกลับคือกับไฟล์ใหม่ล่าสุดในตอนท้ายของรายการstat
พิมพ์วันที่ของไฟล์ในรูปแบบที่มนุษย์สามารถอ่านได้printf
แสดงชื่อแพ็คเกจและวันที่แก้ไขล่าสุด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
ข้อบกพร่องหลักของการแก้ปัญหานี้คือมันไม่ได้ผ่านการทดสอบอย่างดีในการผลิต
/var/lib/dpkg/info/
ได้ นั่นคือเหตุผลที่/var/log/dpkg.log*
อาจจะต้องการการใช้งาน
มันหยาบ แต่ทำงานได้เร็วเท่ากับวิธีแก้ปัญหาอื่น ๆ รูปแบบวันที่คือ 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}'