使用 git 跟踪已安装软件包的列表

400*_*Cat 4 debian apt package-management

我的系统是 Debian Buster。我想用 git 跟踪已安装软件包的列表。

当我用 列出已安装的软件包时dpkg -l,该列表从何而来?

我在 中找到了一些包信息/var/lib/dpkg/status,但该文件包含的信息比我感兴趣的要多。是否还有其他存储包列表的地方?

要跟踪的最佳文件是什么,以便我可以概览已安装的软件包、它们的版本或已卸载的软件包?

更新

我曾尝试使用 git 跟踪 /var/lib/dpkg/status,但输出非常不清楚且令人困惑。状态信息太多了。我只需要跟踪已安装软件包的列表及其版本。类似于 dpkg -l 的输出。

dpkg -l 显示的软件包列表是存储在某个文件中,还是每次都动态生成?

我可以在 /var/lib/dpkg/ 中创建一个 git 存储库并在 git 中创建一些过滤器,以便基本上只跟踪 dpkg -l 的输出吗?或者也许每次我运行 git status` 时,列表都是动态创建的?或任何其他解决方案,我不确定 git 提供了什么可能性。

Ste*_*itt 10

安装的软件包列表/var/lib/dpkg/status; 那是规范参考。已安装的软件包在该文件中通过它们的“安装确定安装”状态发出信号。dpkg -l每次运行时都会处理此文件,并使用存储在其中的信息来生成其输出。

如果您想要一组更简单的数据来跟踪、简化比较,则必须在必要时生成它。

如果您只想跟踪已安装软件包的列表,您可以运行

dpkg --get-selections
Run Code Online (Sandbox Code Playgroud)

定期并将其输出存储在跟踪的文件中git;因为你也想要版本,

dpkg -l
Run Code Online (Sandbox Code Playgroud)

可能更合适。

正如Martin Konrad所指出的,如果您希望能够使用此处生成的信息在以后恢复系统状态,您还应该跟踪手动安装的标记,我也会添加保留:

apt-mark showmanual
apt-mark showhold
Run Code Online (Sandbox Code Playgroud)

您可以将上述所有内容添加到一个dpkg钩子中,以跟踪对系统的所有更改;例如,使用/etc/packages/来保存文件(而不是/var/lib/dpkg,它由“拥有”dpkg并应保持原样),创建一个名为 的文件/etc/dpkg/dpkg.cfg.d/package-history,包含

post-invoke="if [ -x /usr/local/bin/package-history ]; then /usr/local/bin/package-history; fi"
Run Code Online (Sandbox Code Playgroud)

和一个名为/usr/local/bin/package-history包含的文件

#!/bin/sh
cd /etc/packages
dpkg --get-selections > selections
dpkg -l > list
apt-mark showhold > holds
apt-mark showmanual > manual
Run Code Online (Sandbox Code Playgroud)

后者需要是可执行的:

sudo chmod 755 /usr/local/bin/package-history
Run Code Online (Sandbox Code Playgroud)

以上所有命令的输出都已排序,因此无需对它们进行后处理。使用这些文件,您将能够准确地恢复已安装的软件包状态、跟踪版本更改以及查看已删除但未清除的软件包。

您可以添加git commit(第一次检查的变化)的package-history脚本,或者使用etckeeper跟踪变化中的文件/etc/packages,甚至使/etc/packages一个Git仓库本身。使用dpkg钩确保了文件将被更新的任何包更改由,不管驱动aptdpkg或任何其他工具上的顶部捎带dpkg。如果你在package-history脚本本身中提交,那么提交粒度将对应于dpkg执行;如果依赖etckeeper,就会对应动作涉及etckeeper

要处理脚本中的提交,请添加

if [ "$(git status --porcelain | wc -l)" -gt 0 ]; then
    git add *
    git commit -m 'Update package information'
fi
Run Code Online (Sandbox Code Playgroud)

到上面脚本的结尾;然后,您应该以 root 身份手动运行一次,以初始化 git 历史记录(在 之后mkdir /etc/packages; git init /etc/packages)。