按安装日期列出基于 apt 的系统上的软件包

Ela*_*ich 123 debian apt package-management

如何按安装日期列出已安装的软件包?

我需要在 debian/ubuntu 上执行此操作。其他发行版的答案也很好。

我安装了很多东西来编译某段代码,我想获得我必须安装的包的列表。

Mik*_*kel 80

像 Red Hat 这样基于 RPM 的发行版很容易:

rpm -qa --last
Run Code Online (Sandbox Code Playgroud)

在 Debian 和其他基于 dpkg 的发行版上,您的具体问题也很简单:

grep install /var/log/dpkg.log
Run Code Online (Sandbox Code Playgroud)

除非日志文件已被轮换,否则您应该尝试:

grep install /var/log/dpkg.log /var/log/dpkg.log.1
Run Code Online (Sandbox Code Playgroud)

一般来说,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
Run Code Online (Sandbox Code Playgroud)

要回答您关于选择的问题,这是第一遍。

按日期构建包列表

$ 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
Run Code Online (Sandbox Code Playgroud)

构建已安装软件包列表

$ dpkg --get-selections | sed -ne '/\tinstall$/{s/[[:space:]].*//;p}' | \
    sort > ~/dpkglist.selections
Run Code Online (Sandbox Code Playgroud)

加入 2 个列表

$ join -1 1 -2 1 -t $'\t' ~/dpkglist.selections ~/dpkglist.dates \
    > ~/dpkglist.selectiondates
Run Code Online (Sandbox Code Playgroud)

出于某种原因,它没有为我打印很多差异,因此可能存在错误或关于--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
Run Code Online (Sandbox Code Playgroud)

仅列出过去 4 天内安装(更改?)的选项。

您也可以sort在验证使用的排序顺序后删除命令dpkg --get-selections并使find命令更有效。

  • 我通常更喜欢 `apt-get` 而不是 `rpm`,但是现在 debian 因为没有将安装日期保存在数据库中而得到 -1。debian 技巧包括所有已安装的软件包,而不仅仅是 *selected* 软件包,但这是一个好的开始。 (8认同)
  • Debian/Ubuntu:`grep " install " /var/log/dpkg.log` 只列出“安装”行而不显示“状态”行。 (2认同)

Gil*_*il' 24

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 才出现。

  • 正如 Mikel 指出的那样:“最终旧的 /var/log/dpkg.log.* 文件将通过日志轮转删除,因此这种方式不能保证为您提供系统的完整历史记录。”。请参阅此 &lt;https://askubuntu.com/a/948532/723997&gt; 答案,了解如何检测当前顶级包(意味着没有其他包依赖的包) (2认同)

小智 6

粗糙,但有效:

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
Run Code Online (Sandbox Code Playgroud)

  • 嘘,解析 `ls` 的输出的嘶嘶声。请参阅 http://mywiki.wooledge.org/ParsingLs 以了解为什么这是危险的/固有的错误 - 更安全的选择是使用 `find -printf` 或 `stat --format` 来生成一个流毫不含糊地解析。 (2认同)

not*_*bit 6

这是每个人都想要和需要的单线:

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
Run Code Online (Sandbox Code Playgroud)

结果将按时间顺序显示所有(新)安装升级的包。

线路说明:

  • ls -1t-dpkg.log*按时间顺序获取所有文件名
  • zcat -f-如果文件是gzip类型然后解压缩它,否则只传递内容。
  • 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
Run Code Online (Sandbox Code Playgroud)

退税:

  • 如上图,仅适用于ARM架构,架构字段分隔符需要稍作修改
  • 需要放入脚本中以方便别名
  • 尚未在其他 *nix 系统上进行测试


小智 5

/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}。

按照目前的实施,您可以发现您要寻找的信息,但需要进行一些取证处理才能提取详细信息。