假设我有一个 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
从已安装状态转移到另一个状态(以便服务B
可以在A
正常运行时停止并重新启动),但我在文档中找不到任何dpkg
表明这样做的内容。
如果dpkg
不明智地处理这种情况,会吗apt
?
答案1
这是我的经历,而非我读到的内容。
但是,当你破坏 A 时,B 也会被破坏,因为 A 依赖于 B。所以我的问题是 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
1.0.0 全新安装和删除
~/deleteme$ equivs-control a0 ~/deleteme$ nano a0 ... Package: a Version: 1.0.0 ... ~/deleteme$ equivs-build a0
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
Prerm:
包含 的脚本exit 1
。因此,当您尝试安装 A 1.0.1 时, dpkg 将无法删除 A 1.0.0 。
答案2
A
如果已安装软件包的依赖项发生了变化B
,执行后您将看到一个错误,apt-get update && apt-get upgrade
该软件包将被标记为kept back
:
The following packages have been kept back
B-1.0.0
dpkg
不会帮助你,如果有升级可用B-1.0.1
才会apt-get dist-upgrade
有帮助。