当您升级Debian软件包时,依赖的Debian软件包会发生什么情况?

假设我有一个Debian软件包A-1.0.0.deb(其中包含一个库),还有另一个软件包B-1.0.0.deb(其中包含一个服务),该服务依赖于A库。现在假设我想升级到A-1.0.1.deb。
根据这份文档,dpkg会通过一个相当复杂的算法来确定在升级过程中为每个软件包调用哪些软件包维护脚本。如果其中一些步骤失败,那么A可能会处于某种悬而未决的状态(例如,“半安装”)。
然而,当你打破A时,B也会被破坏,因为它依赖于A。所以我的问题是,dpkg是否有任何内置的方法来处理这种情况?B的安装状态是否会根据A的状态而改变?理想情况下,dpkg应该具有一些内置功能,可以将B从已安装状态移动到另一个状态(这样当A健康时,B服务可以停止和重新启动),但我在dpkg文档中找不到任何相关信息。
如果dpkg不能智能处理这种情况,那么apt呢?
2个回答

从我所经历的,而不是我所读到的。
然而,当你打破A时,B也会被破坏,因为A依赖于它。所以我的问题是,dpkg是否有任何内置的方法来处理这种情况?
是的,在下一次运行时,它将尝试重新安装或重新配置A。
如果只是中断了,它会修复并继续正常工作。
但如果是控制脚本的问题,它会一次又一次地失败,并停留在这个循环中。那么这就是一个错误,需要对该软件包进行报告,并需要手动修复。
B的安装状态是否取决于A的状态?
不,状态保持为已安装,没有变化,但它确实会跟踪损坏的依赖关系,至少不在同一个文件/var/lib/dpkg/status中。
如果dpkg不能智能地处理这种情况,apt会吗?
不会,APT在这种情况下不会干涉。apt使用dpkg,dpkg是较低级别的工具,它是唯一实际安装、构建和删除Debian软件包的工具。
让我们试试吧,最好在虚拟机中完成。
准备虚拟包
~$ sudo apt install equivs ~$ mkdir deleteme ~$ cd deleteme B 1.0.0 依赖于 A
~/deleteme$ equivs-control b0 ~/deleteme$ nano b0 ... Package: b Version: 1.0.0 ... Depends: a ... ~/deleteme$ equivs-build b0
A 1.0.0 清洁安装和删除
~/deleteme$ equivs-control a0 ~/deleteme$ nano a0 ... Package: a Version: 1.0.0 ... ~/deleteme$ equivs-build a0
A 1.0.1 脏安装,但是干净删除
~/deleteme$ cp a0 a1 ~/deleteme$ nano a1 ... Package: a Version: 1.0.1 ... Postinst: a1.postinst ...
~/deleteme$ nano a1.postinst
#!/bin/sh exit 1
~/deleteme$ equivs-build a1
现在,你应该有:
~/deleteme$ ls -1 a0 a1 a_1.0.0_all.deb a_1.0.1_all.deb a1.postinst b0 b_1.0.0_all.deb
尝试这个场景
sudo su
dpkg -i b_1.0.0_all.deb dpkg --audit dpkg -i a_1.0.0_all.deb dpkg --audit dpkg --configure -a dpkg --audit dpkg --remove a dpkg --remove b dpkg --remove a
dpkg -i a_1.0.0_all.deb dpkg -i b_1.0.0_all.deb dpkg --audit dpkg -i a_1.0.1_all.deb dpkg --audit dpkg --remove a apt purge a
为了陷入一个无法完成安装也无法删除的循环中。
创建干净的 A 1.0.1,B 1.0.0,但是 A 1.0.0 包含一个包含 exit 1 的 Prerm 脚本。因此,当您尝试安装 A 1.0.1 时,dpkg 将无法删除 A 1.0.0。

如果依赖关系中的安装包 B 发生了变化,执行 apt-get update && apt-get upgrade 后会出现错误,该包将被标记为 kept back:
The following packages have been kept back
B-1.0.0

如果有可升级的版本,dpkg 是无法帮助你的,只有apt-get dist-upgrade才能提供帮助。