如何按安装日期列出已安装的软件包?
我需要在debian / ubuntu上执行此操作。其他分布的答案也将很好。
我安装了很多东西来编译某些代码,并且我想获得必须安装的软件包的列表。
如何按安装日期列出已安装的软件包?
我需要在debian / ubuntu上执行此操作。其他分布的答案也将很好。
我安装了很多东西来编译某些代码,并且我想获得必须安装的软件包的列表。
Answers:
像Red Hat这样基于RPM的发行版很容易:
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
,但是现在debian由于未在数据库中保存安装日期而得到-1。debian技巧包括所有已安装的软件包,而不仅仅是选定的软件包,但这是一个好的开始。
half-installed
这样做,您的工作量就会减少(删除条目):grep install\ /var/log/dpkg.log
grep " install " /var/log/dpkg.log
仅列出“安装”行,而不显示“状态”行。
Mikel展示了如何在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
应该会有所帮助。另外,可能还没有听说有人会用\n\t\r\v
它的名字命名APT软件包。
该/var/log/apt/history.log
文件的格式笨拙,恕我直言。
开始日期:{date} {time}命令行:{command} {options ...}安装:{package(version)},...,{package(version)},... End-Date:{date } {时间}
我本来希望有更多日志文件格式的记录
{date} {time} {tab} {package} {tab} {version} {tab} {command} {options} \ n
或一些XML,不仅显示{package},还显示任何{dependencies}。
按照当前的实施方式,您可以发现所需的信息,但是需要进行一些取证处理才能提取出详细信息。
这对我在Debian系统上有效,我猜测文件格式自2011年以来已经更改。该系统非常新,因此我不希望它在较旧的系统上运行,尽管这可能只需要解压缩日志并使用引用所有这些的问题。
grep 'install ' /var/log/dpkg.log.1 | sort | cut -f1,2,4 -d' '
文件每一行的前两个字段/var/log/dpkg.log
是日期和时间。请注意grep部分中带有install的尾随空格,这是因为升级可以触发安装,但是如果我理解正确的话,您想知道用户安装了什么。
这是每个人都想要和需要的一线客:
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
- 逐行反向输出cat,以确保我们获得正确的时间顺序。grep
-仅检查已安装或升级的软件包。awk -F ':a'
-将架构字段与包名称分开column -t
-漂亮地打印以空格分隔的列一个人当然想为此做一个别名,但是不幸的是,这是不可能的,因为awk依赖于单引号和双引号。在这方面,最好将其放入bash脚本中,并在字段列中:
更好地处理分隔符以用于其他体系结构。
输出为:
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
退税:
注意这一点是因为您提到欢迎其他分发答案。rpm具有大量的输出格式标签,其中之一是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没有用于解决此问题的内置工具,但是有关以标准方式安装的程序的所有信息都保存在文件程序名.list的文件中,该文件位于/ var / lib / dpkg / info /位置。但是,那里没有有关手动安装程序的信息。
一个长的单行解决方案:
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}'