github编辑

5.3 使用 pkg 管理二进制包

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

如何从 Port 构建出 pkg

pkg 构建流程图

书里明确写有某个包,但是 pkg 安装的时候却提示没有

这个问题一般来说有两种情况:

  • ① 在 Ports 中的确没有这个 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

最后更新于