升级 Debian 软件包时,依赖的 Debian 软件包会发生什么变化?

Ric*_*art 5 package-management apt dpkg deb

假设我有一个 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吗?

use*_*.dz 6

从我所经历的而不是我所读到的。

  • 然而,当你破坏 A 时,B 也会被破坏,因为 A 依赖于它。所以我的问题是 dpkg 是否有任何内置方法来处理这种情况?

    是的,它会在下次运行时尝试重新安装或重新配置 A。

    1. 如果它只是被中断,它会修复它并继续正常工作。

    2. 但这是控制脚本的问题,它会一次又一次地失败并停留在这个循环中。然后它是一个错误,将针对该包填写报告,并且需要手动修复。

  • B 的安装状态是否会根据 A 的状态而变化?

    不,状态保持为 Installed 没有变化,但它也跟踪破坏的依赖关系,至少不在同一个文件中/var/lib/dpkg/status

  • 如果 dpkg 不能智能地处理这种情况,是否 apt?

    不,在这种情况下,APT 不会干扰。apt使用dpkg, dpkg 是较低级别的工具,它是唯一实际安装、构建、删除 Debian 软件包的工具。


让我们尝试一下,最好在 virtualbox 中完成。

  1. 准备虚拟包

    ~$ sudo apt install equivs
    ~$ mkdir deleteme
    ~$ cd deleteme
    
    Run Code Online (Sandbox Code Playgroud)

    B 1.0.0 取决于 A

    ~/deleteme$ equivs-control b0
    ~/deleteme$ nano b0
    ...
    Package: b
    Version: 1.0.0
    ...
    Depends: a
    ...
    ~/deleteme$ equivs-build b0
    
    Run Code Online (Sandbox Code Playgroud)

    1.0.0 全新安装和删除

    ~/deleteme$ equivs-control a0
    ~/deleteme$ nano a0
    ...
    Package: a
    Version: 1.0.0
    ...
    ~/deleteme$ equivs-build a0
    
    Run Code Online (Sandbox Code Playgroud)

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

    现在,你应该有:

    ~/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
    
    Run Code Online (Sandbox Code Playgroud)
  2. 试试这个场景

    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
    
    Run Code Online (Sandbox Code Playgroud)
  3. 要进入无法完成安装的循环,也不能将其删除。

    创建干净的 A 1.0.1、B 1.0.0 但使用Prerm:包含exit 1. 因此,当您尝试安装 A 1.0.1 时, dpkg 将无法删除 A 1.0.0 。