如何按安装日期列出已安装的软件包?
我需要在 debian/ubuntu 上执行此操作。其他发行版的答案也很好。
我安装了很多东西来编译某段代码,并且我想获取必须安装的软件包的列表。
答案1
基于 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
命令更有效。
答案2
Mikel 已经展示了如何在 dpkg 级别做到这一点。特别是,/var/lib/dpkg/info/$packagename.list
是在安装包时创建的(并且之后不会修改)。
如果您使用过 APT 工具(您可能会这样做,因为您担心自动安装的软件包与手动安装的软件包),那么/var/log/apt/history.log
.只要它没有旋转,它就会跟踪所有 APT 安装、升级和删除,并为标记为自动安装的软件包提供注释。这是一个相当新的功能,在 APT 0.7.26 中引入,因此在 Debian 中它出现在 squeeze 中。在 Ubuntu 中,10.04 有,history.log
但自动安装的注释直到 10.10 才出现。
答案3
这是每个人都想要和需要的一句话:
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
-如果文件是压缩包输入然后解压它,别的只是传递内容。tac
- 反向输出猫,逐行确保我们得到正确的时间顺序。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
退税:
- 如上图,仅适用于ARM架构,架构字段分隔符需要稍作修改
- 需要放入脚本中以便于使用别名
- 尚未在其他 *nix 系统上进行测试
答案4
恕我直言,该/var/log/apt/history.log
文件的格式很尴尬。
开始日期:{日期} {时间} 命令行:{命令} {选项 ...} 安装:{程序包(版本)},...,{程序包(版本)},... 结束日期:{日期} {时间}
我更喜欢日志文件格式的记录
{日期}{时间}{选项卡}{包}{选项卡}{版本}{选项卡}{命令}{选项}\n
或一些 XML 不仅显示 {package},还显示任何 {dependency}。
按照目前的实施方式,您可以发现所需的信息,但需要进行一些取证处理才能提取详细信息。