5.3 使用 pkg 管理二进制包

本章系统讲解 FreeBSD 二进制包管理器 pkg 的核心功能与使用方法。pkg 作为 FreeBSD 现代包管理体系的核心组件,提供了高效、可靠的软件安装、更新与卸载机制,是 FreeBSD 用户进行第三方软件管理的主要工具。

FreeBSD 的二进制包管理器目前是 pkg(旧称 pkgng),名称来源于英文单词"Package",即软件包的简称。

对于熟悉 Linux 发行版的读者而言,FreeBSD 的包管理方案可类比于两大 Linux 发行版包管理器的功能组合:

  • Arch Linux:Pacman,对应 pkg(同样秉持 KISS 的理念)

  • Gentoo Linux:Portage,对应 Ports(Portage 本身就是 Ports 的仿制品)

pkg install 可以缩写成 pkg ins,其他命令亦类似。

注意

pkg 只能管理第三方软件包,并不能起到升级系统,获取安全更新的作用。这是因为 FreeBSD 项目是将内核与用户空间作为一个整体来进行维护的,而不是像 Linux 那样 Linus Torvalds 负责维护内核,各个发行版的人负责维护 GNU 工具(他们这些软件实际上被设计为单个软件包,因此可以用包管理器更新与升级系统)。

FreeBSD 现在也正 试图使用 pkg 来实现用户空间和内核的更新arrow-up-right 备份arrow-up-right ,以期解决上述问题。

FreeBSD 使用 freebsd-update 来升级系统,获取安全补丁。https://pkg-status.freebsd.org/arrow-up-right 可以查看当前的 pkg 编译状态。

偏好图形化的用户可以安装并使用 ports-mgmt/octopkg,该工具是 pkg 的图形化前端,由 GhostBSD 开发。

技巧

如果需要查询某个软件包在 FreeBSD 中的具体情况,可以这样做:使用 Google 或 Bing(Bing 很多时候搜索不出来)搜索“freebsd ports 包名”。如果无法使用,可以直接在网站里搜索包名 https://www.freshports.org/arrow-up-right

从 Ports 构建二进制包的流程

Ports 框架可以将源代码编译并打包成 pkg 格式的二进制包,这一构建过程涉及多个有序的执行步骤。下面的流程图展示了完整的构建流程,为理解这一机制提供了直观的参考依据。

pkg 构建流程图

常见问题:教材中提及的包在 pkg 中无法找到

当遇到教材中明确提及的软件包在使用 pkg 安装时提示不存在的情况,一般可以归纳为以下两种主要原因:

  • 情况一:Ports 中确实不存在该 Port,可能的原因包括教材内容有误、该 Port 已从 Ports 集合中移除或已更名等

  • 情况二:Ports 中确实存在该 Port,但 FreeBSD 的 pkg 包是周期性构建的(与 Ports 自身的更新同步),因此时常会出现暂时没有对应 pkg 二进制包的情况

具体是哪个问题造成的,建议查询 https://www.freshports.orgarrow-up-right,上面会显示软件包的依赖情况和 pkg 包的构建情况。

本书中一般会同时列出 Ports 安装方式,比如要查 Port x11/budgie,你可以这么做:直接访问 https://www.freshports.org/x11/budgie/arrow-up-right

一般来说,如果 Ports 中有该 Port,但 pkg 中暂时没有,等待 7–14 天通常即可(构建失败的包系统会自动向维护者报告错误)。如要立刻安装使用,请使用 Ports。

附录:FreeBSD 软件包原子更新的困难与现状分析

FreeBSD 镜像站(无论是官方的还是非官方的)的软件源存在以下典型现象,这些现象直接反映了当前软件包更新机制的技术特点:

  • 一旦某个 Port 发生更新,就会立即从软件源中撤销由该 Port 衍生的 pkg 二进制包,直到下次构建出新的 pkg 软件包,而非保留旧版本软件包;

  • 只要开始一次新的构建,旧版本软件包不会被临时保留,而是被立即从 pkg 软件源中删除,直到构建出新版本的 pkg 软件包。

针对上述现象,理论上的一种解决方案是:保持软件包处于某一固定版本阶段(如季度分支),暂不进行更新,然后直接进行版本轮替。

问题在于 Port 更新是不定时的。复杂的依赖会破坏一切。有能力者可尝试提出新的看法和建议,并反馈至下方或 FreeBSD 论坛arrow-up-right 备份arrow-up-right

思考题

试一试:帮助 FreeBSD 项目实现 pkg 二进制软件包的原子更新?

安装 pkg 包管理器本体

技巧

根据 man pkg(7)arrow-up-right 页面解释:

为了避免出现向后兼容问题,实际的 pkg(8) 工具不会预装在基本系统中。

基本系统默认不包含 pkg,需要先下载并安装 pkg:

技巧

如果长时间卡在 Bootstrapping pkg from ……, please wait...,请按 Ctrl + C 中断这一过程,换境内源后再进行。

技巧

如果提示 00206176BC680000:error:0A000086:SSL routines:tls_post_process_server_certificate:certificate verify failed:/usr/src/crypto/openssl/ssl/statem/statem_clnt.c:1890:(SSL 证书验证失败),请先校准时间。

思考题

在 SSL 大行其是的年代里,任何网络问题总是要看看自己机器的时间是否正确。而一般人总会忽略这一点(有时候甚至是 CPU 中负责加密的模块损坏导致的),并且大多数情况下报错也极不明确。你认为应该如何解决这个问题?

使用 pkg 安装软件

以安装 chromium 为例:

“Insufficient privileges to install packages”即“没有足够的权限来安装软件包”。

再试一次:

思考题

Add Concurrent Downloads of Multiple Packagesarrow-up-right 备份arrow-up-right

你会发现 pkg 既不支持并行下载也不支持并行安装,阅读源代码,尝试解决这个问题并提交 PR。

你极有可能会遇到这种情况:

“pkg: No packages available to install matching 'chromium' have been found in the repositories”即“pkg:在仓库中找不到与 chromium 匹配、可供安装的软件包”。

如果你前面显示了“FreeBSD repository update completed. 36804 packages processed.”(FreeBSD 仓库更新完成。处理了 36804 个包),说明当前软件源是可用的,只是找不到 chromium 这个软件包而已。

这就是上面所述的缺乏“原子更新”的表现。

还会发现,即使系统已设置 i18n,pkg 的输出仍然是英文。

思考题

Is it possible to add i18n multilingual support using po files?arrow-up-right 备份arrow-up-right

FreeBSD 基本系统里没有 gettext,所以没有计划这样做,如果后续在 pkg 中出现可用的 libintl 套件,则可能会重新考虑。

阅读 pkg 源代码,定位问题所在源头,尝试解决这个问题,提交 PR 让 pkg 支持 i18n。

pkg 更新软件

错误:You must upgrade the ports-mgmt/pkg port first(必须先更新 pkg 本体)

解决:

查看已经安装的所有软件

卸载软件

直接使用 pkg delete 可能破坏依赖关系,应尽量避免使用(Ports 的 make deinstall 亦然),建议改用 pkg_rmleaves 命令,该命令所属的软件需要自行安装。

或者

如何卸载所有自行安装的第三方软件?

参考文献

列出 pkg 包安装的文件

技巧

pkg 的下载路径是 /var/cache/pkg/

注意

只能列出已安装的包的文件,未安装的不能用这个命令。

查找缺少的 .so(适用于 Linux 兼容层)

警告

本节仅针对 Linux 兼容层缺少 .so 文件的问题。如果你是在 FreeBSD 中遇到了此类问题,应首先更新系统。然后再更新软件源和软件。

安装 pkg-provides

或者:

配置使用 pkg-provides

  • 查看配置说明:

  • 编辑 /usr/local/etc/pkg.conf,找到空行,写入:

  • 运行:pkg plugins

  • 刷新数据库:

示例:查找 libxcb-icccm.so.4

故障排除与未竟事宜

ld-elf.so.1: Shared object "libmd.so.6" not found, required by "pkg"

该问题通常是由于软件源未及时同步基本系统 ABI 的变更所致。

对于一般 RELEASE,更新系统即可。对于 CURRENT/STABLE 系统,重新编译 pkg 即可。

RELEASE

请先切换到 latest 源,再使用软件源里的 pkg 包重装 pkg:

若无效,则再:

CURRENT/STABLE

pw: user ‘package’ disappeared during update

问题示例:

问题原因在于用户数据库未同步。

根据 /etc/master.passwd 更新密码数据库:

Shared object "x.so.x" not found, required by "xxx"

出现该问题通常是由于 ABI 发生破坏,更新即可解决。

使用 pkg 安装 bsdadminscripts2

或者使用 ports 安装 bsdadminscripts2

检查已安装软件包的动态库依赖是否完整:

按照上述软件列表,使用 Ports 逐个重新编译即可(RELEASE 可以直接 pkg 更新。)。

附录:bsdadminscripts2 扩展用法及参考文献

验证已安装软件包的完整性和一致性:

  • bsdadminscripts2 亦可查找当前系统的过时软件:

Newer FreeBSD version for package pkg

问题示例:

这通常发生在已失去安全支持的系统,或 CURRENT/STABLE 分支系统上,不影响使用,输入 y 即可。

如果想要从根源上解决,需要自己卸载 pkg,从 ports 安装 ports-mgmt/pkg;或者从源代码更新整个系统。

如果只是不想看到这个提示:只需要按照提示将 IGNORE_OSVERSION=yes 写到 /etc/make.conf 里面(没有就新建)就行。

pkg: An error occurred while fetching package: No error

以 root 权限执行 certctl rehash 刷新证书即可。

参见 pkg(8): "An error occured while fetching package: No error"arrow-up-right 备份arrow-up-right

最后更新于