查询 dpkg 从默认映像中安装/删除的所有软件包

查询 dpkg 从默认映像中安装/删除的所有软件包

有什么方法可以查询dpkg自系统基础安装以来添加/删除了哪些软件包?

我正在运行 Debian 5。

答案1

据我所知,没有直接的方法可以做到这一点。dpkg数据库仅包含包的当前状态,因此任何历史记录都必须从日志中推断或解析。


简短回答(又称懒人单行回答)

dpkg-query -f='${Package}\n' -W  | grep -vx "`grep 'Setting up' /var/log/installer/syslog | cut -d' ' -f8`"

解释

1. 获取安装程序安装的软件包列表

debian-installer将其日志写入/var/log/installer。那里有一个syslog文件,我们可以grep通过它查看安装了哪些软件包:

grep 'Setting up' /var/log/installer/syslog

请注意,我们正在寻找配置或者拆开而不是例如。选择因为我们需要所有软件包,包括作为依赖项安装的软件包。我们需要从中提取软件包名称:

grep 'Setting up' /var/log/installer/syslog | cut -d' ' -f8

2. 获取当前安装的软件包列表

现在我们需要一个当前安装的软件包列表来执行此reverse grep操作。我们只需要软件包名称,例如不需要描述,以避免过滤掉太多内容,因此简单明了dpkg -l并不好。我们可以改用dpkg-query

dpkg-query -f='${Package}\n' -W

3. 过滤启动时安装的软件包

剩下要做的就是从第二个列表中过滤掉第一个列表的内容。为此,我们使用grep -vx.-v表示“反向”,-x(或--line-regex)表示“精确”。后者仅匹配整行,以确保我们过滤掉例如。易于但不是资质

以下是整个事情的经过:

 # currently installed
 current="`dpkg-query -f='${Package}\n' -W`"
 # base install (let's also remove duplicates to make verification easier)
 base="`grep 'Setting up' /var/log/installer/syslog | cut -d' ' -f8 | sort | uniq`"
 # your answer
 extra="`echo "$current" | grep -vx "$base"`"
 removed="`echo "$base" | grep -vx "$current"`"

4. 验证结果

为了检查我们是否获得了正确的包,我们可以计算以下行:

 echo "$base" | wc -l         # 160
 echo "$current" | wc -l      # 1677
 echo "$extra" | wc -l        # 1517
 echo "$removed" | wc -l      # 0 (I used "netinst")

更新:如果/var/log/installer不存在

/var/log/installer如果软件包被清除,则会从系统中删除installation-report。在这种情况下,我们可以尝试从最旧的文件中获取安装程序加载的软件包列表/var/log/dpkg.log.*

其中存在两个问题:

  1. 由于这些文件已经轮换,所以不能保证我们需要的信息仍然存在(在我的情况下仍然存在 - 安装于 2010-10-01 并且从那时起进行了大量更新)。
  2. 最旧的文件可能包含正在安装的软件包的日志初始安装。

对于 (1) 我们无能为力。对于 (2),我们可以手动(可能通过时间戳)确定哪个包在 之前完成安装debian-installer。就我而言,它似乎是os-prober(我相信在某些情况下这可能很常见,因为它与 有关系grub)。

以下是$base使用此方法的示例代码:

 last_installed="os-prober"
 base_dpkglog="`zgrep ' install ' dpkg.log.8.gz | cut -d' ' -f4 | while read pkg; do 
     [ "$pkg" != "$last_installed" ] && echo $pkg || { echo $pkg; break; }
 done | sort | uniq`"

快速验证一下:

 echo "$base_dpkglog" | wc -l                    # 159
 echo "$base" | wc -l                            # 160
 diff -d <(echo "$base") <(echo "$base_dpkglog") # 31d30
                                                 # < dpkg

相关内容