Product SiteDocumentation Site

5.2. 软件包元信息

The Debian package is not only an archive of files intended for installation. It is part of a larger whole, and it describes its relationship with other Debian packages (dependencies, conflicts, suggestions). It also provides scripts that enable the execution of commands at different stages in the package's lifecycle (installation, removal, upgrades). These data are used by the package management tools but are not part of the packaged software; they are, within the package, what is called its “meta-information” (information about other information).

5.2.1. 描述:control 文件

This file uses a structure similar to email headers (as defined by RFC 2822). For example, for apt, the control file looks like the following:
$ apt-cache show apt
Package: apt
Version: 1.0.9.6
Installed-Size: 3788
Maintainer: APT Development Team <deity@lists.debian.org>
Architecture: amd64
Replaces: manpages-it (<< 2.80-4~), manpages-pl (<< 20060617-3~), openjdk-6-jdk (<< 6b24-1.11-0ubuntu1~), sun-java5-jdk (>> 0), sun-java6-jdk (>> 0)
Depends: libapt-pkg4.12 (>= 1.0.9.6), libc6 (>= 2.15), libgcc1 (>= 1:4.1.1), libstdc++6 (>= 4.9), debian-archive-keyring, gnupg
Suggests: aptitude | synaptic | wajig, dpkg-dev (>= 1.17.2), apt-doc, python-apt
Conflicts: python-apt (<< 0.7.93.2~)
Breaks: manpages-it (<< 2.80-4~), manpages-pl (<< 20060617-3~), openjdk-6-jdk (<< 6b24-1.11-0ubuntu1~), sun-java5-jdk (>> 0), sun-java6-jdk (>> 0)
Description-en: commandline package manager
 This package provides commandline tools for searching and
 managing as well as querying information about packages
 as a low-level access to all features of the libapt-pkg library.
 .
 These include:
  * apt-get for retrieval of packages and information about them
    from authenticated sources and for installation, upgrade and
    removal of packages together with their dependencies
  * apt-cache for querying available information about installed
    as well as installable packages
  * apt-cdrom to use removable media as a source for packages
  * apt-config as an interface to the configuration settings
  * apt-key as an interface to manage authentication keys
Description-md5: 9fb97a88cb7383934ef963352b53b4a7
Tag: admin::package-management, devel::lang:ruby, hardware::storage,
 hardware::storage:cd, implemented-in::c++, implemented-in::perl,
 implemented-in::ruby, interface::commandline, network::client,
 protocol::ftp, protocol::http, protocol::ipv6, role::program,
 role::shared-lib, scope::application, scope::utility, sound::player,
 suite::debian, use::downloading, use::organizing, use::searching,
 works-with::audio, works-with::software:package, works-with::text
Section: admin
Priority: important
Filename: pool/main/a/apt/apt_1.0.9.6_amd64.deb
Size: 1107560
MD5sum: a325ccb14e69fef2c50da54e035a4df4
SHA1: 635d09fcb600ec12810e3136d51e696bcfa636a6
SHA256: 371a559ce741394b59dbc6460470a9399be5245356a9183bbeea0f89ecaabb03

5.2.1.1. 依赖:Depends

The dependencies are defined in the Depends field in the package header. This is a list of conditions to be met for the package to work correctly — this information is used by tools such as apt in order to install the required libraries, in appropriate versions fulfilling the dependencies of the package to be installed. For each dependency, it is possible to restrict the range of versions that meet that condition. In other words, it is possible to express the fact that we need the package libc6 in a version equal to or greater than “2.15” (written “libc6 (>= 2.15)”). Version comparison operators are as follows:
  • <<:小于;
  • <=:小于或等于;
  • =: equal to (note that “2.6.1” is not equal to “2.6.1-1”);
  • >=:大于或等于;
  • >>:大于。
In a list of conditions to be met, the comma serves as a separator. It must be interpreted as a logical “and”. In conditions, the vertical bar (“|”) expresses a logical “or” (it is an inclusive “or”, not an exclusive “either/or”). Carrying greater priority than “and”, it can be used as many times as necessary. Thus, the dependency “(A or B) and C” is written A | B, C. In contrast, the expression “A or (B and C)” should be written as “(A or B) and (A or C)”, since the Depends field does not tolerate parentheses that change the order of priorities between the logical operators “or” and “and”. It would thus be written A | B, A | C.
The dependencies system is a good mechanism for guaranteeing the operation of a program, but it has another use with “meta-packages”. These are empty packages that only describe dependencies. They facilitate the installation of a consistent group of programs preselected by the meta-package maintainer; as such, apt install meta-package will automatically install all of these programs using the meta-package's dependencies. The gnome, kde-full and linux-image-amd64 packages are examples of meta-packages.

5.2.1.2. 冲突:冲突字段

The Conflicts field indicates when a package cannot be installed simultaneously with another. The most common reasons for this are that both packages include a file of the same name, or provide the same service on the same TCP port, or would hinder each other's operation.
dpkg will refuse to install a package if it triggers a conflict with an already installed package, except if the new package specifies that it will “replace” the installed package, in which case dpkg will choose to replace the old package with the new one. apt always follows your instructions: if you choose to install a new package, it will automatically offer to uninstall the package that poses a problem.

5.2.1.3. 不相容性:中断字段

中断字段有一个影响和冲突字段类似,但它具有特殊的意义。它标志着一个包的安装会将另外一个包(或者是特定版本)中断掉。通常而言,两个包之间的不兼容是短暂的,中断关系会特别指出那些不兼容的版本。
dpkg will refuse to install a package that breaks an already installed package, and apt will try to resolve the problem by updating the package that would be broken to a newer version (which is assumed to be fixed and, thus, compatible again).
不向后兼容的更新可能会发生这种情况:如果新版本与旧版本的功能不在另一个程序中做特别规定,这将导致故障。中断字段会防止用户继续运行从而遇到这些问题。

5.2.1.4. 预备好的条目:预备字段

这个字段引入了一个很有意思的“虚拟包”的概念。它有很多的角色,但有两个特别重要。第一个是由使用虚拟包关联到的一个通用的服务(包“预备”了这些服务)。第二个表示一个包完全取代了另外一个,所以它也能满足依赖性要求。因此,可以创建一个替换而不必使用相同的包名称的包。
5.2.1.4.1. 提供一个“服务”
Let us discuss the first case in greater detail with an example: all mail servers, such as postfix or sendmail are said to “provide” the mail-transport-agent virtual package. Thus, any package that needs this service to be functional (e.g. a mailing list manager, such as smartlist or sympa) simply states in its dependencies that it requires a mail-transport-agent instead of specifying a large yet incomplete list of possible solutions (e.g. postfix | sendmail | exim4 | …). Furthermore, it is useless to install two mail servers on the same machine, which is why each of these packages declares a conflict with the mail-transport-agent virtual package. A conflict between a package and itself is ignored by the system, but this technique will prohibit the installation of two mail servers side by side.
5.2.1.4.2. 和另一个软件包的可交互性
The Provides field is also interesting when the content of a package is included in a larger package. For example, the libdigest-md5-perl Perl module was an optional module in Perl 5.6, and has been integrated as standard in Perl 5.8 (and later versions, such as 5.20 present in Jessie). As such, the package perl has since version 5.8 declared Provides: libdigest-md5-perl so that the dependencies on this package are met if the user has Perl 5.8 (or newer). The libdigest-md5-perl package itself has eventually been deleted, since it no longer had any purpose when old Perl versions were removed.
使用了预备字段来避免中断依赖性关系

图 5.1. 使用了预备字段来避免中断依赖性关系

这个功能非常有用,因为它是永远不可能预料到变化莫测的发展,它不能够调整重命名,或者其他自动替换过的软件,所以它是必要的。
5.2.1.4.3. Past Limitations
Virtual packages used to suffer from some limitations, the most significant of which was the absence of a version number. To return to the previous example, a dependency such as Depends: libdigest-md5-perl (>= 1.6), despite the presence of Perl 5.10, would never be considered as satisfied by the packaging system — while in fact it most likely is satisfied. Unaware of this, the package system chose the least risky option, assuming that the versions do not match.
This limitation has been lifted in dpkg 1.17.11, and is no longer relevant in Jessie. Packages can assign a version to the virtual packages they provide with a dependency such as Provides: libdigest-md5-perl (= 1.8).

5.2.1.5. 替换文件:替换字段

The Replaces field indicates that the package contains files that are also present in another package, but that the package is legitimately entitled to replace them. Without this specification, dpkg fails, stating that it can not overwrite the files of another package (technically, it is possible to force it to do so with the --force-overwrite option, but that is not considered standard operation). This allows identification of potential problems and requires the maintainer to study the matter prior to choosing whether to add such a field.
当软件包名称变更时,或者当一个软件包包含在另外一个的时候,此字段的使用是合理的。这也发生在维护者决定从来自相同的源码包的大量二进制包里分发出文件:一个替换的文件不再属于旧的软件包,只有新的才属于。
如果已安装软件包的所有文件都被替换了,那么该软件包将认为将被删除掉。最后,这个字段会鼓励dpkg命令去删除替换掉有冲突的包。

5.2.2. 配置脚本

除了控制文件之外,每个Debian软件包可能在control.tar.gz的存档中包含了一些脚本,这些脚本在软件包处理的不同的阶段被dpkg调用。Debian政策描述了一些可能的细节,在可能的情况下,指定脚本调用它们所收到的参数。这些顺序可能比较复杂,因为如果脚本中任何一步出现问题的时候,dpkg进程会通过取消安装或者卸载来尝试恢复到一个令人满意的状态(只要是可能的)。
在一般情况下,preinst脚本会在安装软件包前执行,而postinst会稍候执行。同样,prerm会在移除一个软件包的前和postrm之后。更新软件包相当于是清除掉以前的旧版本并且安装新的软件包。所以在这里我们不可能来详细描述所有的可能的方案,但我们将讨论最常见的两种:安装/更新和移除。

5.2.2.1. 安装和升级

这里告诉你,安装的时候发生了什么(或者是更新)
  1. 对于升级,dpkg会调用old-prerm 升级新版本
  2. 还是对于升级,dpkg执行new-preinst 升级旧版本;对于第一个安装,它会执行new-preinst 安装。它可能会增加旧版本的最后一个参数,如果软件包已经被安装或者是删除了(但没有清除合并掉旧版本,那么这个配置文件会被保留)。
  3. 新的软件包文件被解压。如果文件已经存在,就被会替换,同时会产生一个临时的备份副本。
  4. 对于更新,dpkg执行old-postrm 升级新版本
  5. dpkg更新所有的内部数据(文件爱女列表,配置脚本等),并删除被替换文件的备份。这是一条不归路: ) dpkg将不再具有访问所有元素的需要以此来返回以前的状态。
  6. dpkg will update the configuration files, asking the user to decide if it is unable to automatically manage this task. The details of this procedure are discussed in 第 5.2.3 节 “校验,配置文件列表”.
  7. 最后,dpkg 通过执行 new-postinst configure 最近一次配置的版本号 对软件包进行配置。

5.2.2.2. 软件包移除

这里是当移除一个软件包的时候发生了什么:
  1. dpkg 回调prerm 移除
  2. dpkg 移除了所有的软件包文件,只剩下了配置文件和配置的脚本。
  3. dpkg executes postrm remove. All of the configuration scripts, except postrm, are removed. If the user has not used the “purge” option, the process stops here.
  4. 对于一个完整的清除包(由dpkg --purgedpkg -P发出的),配置文件也将会被删除,同时一些副本(*.dpkg-tmp,*.dpkg-old,*.dpkg-new)和缓存文件也会被删除掉;dpkg这时会执行postrm purge
The four scripts detailed above are complemented by a config script, provided by packages using debconf to acquire information from the user for configuration. During installation, this script defines in detail the questions asked by debconf. The responses are recorded in the debconf database for future reference. The script is generally executed by apt prior to installing packages one by one in order to group all the questions and ask them all to the user at the beginning of the process. The pre- and post-installation scripts can then use this information to operate according to the user's wishes.

5.2.3. 校验,配置文件列表

In addition to the maintainer scripts and control data already mentioned in the previous sections, the control.tar.gz archive of a Debian package may contain other interesting files. The first, md5sums, contains the MD5 checksums for all of the package's files. Its main advantage is that it allows dpkg --verify (which we will study in 第 14.3.3.1 节 “Auditing Packages with dpkg --verify) to check if these files have been modified since their installation. Note that when this file doesn't exist, dpkg will generate it dynamically at installation time (and store it in the dpkg database just like other control files).
conffiles lists package files that must be handled as configuration files. Configuration files can be modified by the administrator, and dpkg will try to preserve those changes during a package update.
实际上,在这种情况下,dpkg的行为会尽可能地智能:如果两个版本之间并没有改变标准的配置文件,那么dpkg就什么也不会作。但是,如果文件已经被修改,它会尝试更新此文件。这会产生两种可能的情况:一是管理员没有碰配置文件,在这种情况下dpkg会自动安装新版本;二是文件已经被修改了,在这种情况下dpkg会询问管理员希望使用哪个版本(旧版本或者新的)。为了帮助用户作出选择,dpkg会提供“差异”,这会显示两个版本之间的差异。如果用户选择保留旧的版本,新的将被存储在文件夹的同一个位置并以.dpkg-dist为后缀名的文件中。另外一个可能的操作是由暂时中断的dpkg来编辑该文件,并试图重新恢复相关的修改(之前被验证的差异)。