5.4 使用 pkg 管理二进制包

FreeBSD 二进制包管理器目前是 pkg(旧称 pkgng),即“Package”,软件包的意思。

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

注意

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

FreeBSD 现在也正 试图使用 pkg 来实现用户空间和内核的更新。解决上述问题。

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

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

技巧

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

如何从 Port 构建出 pkg

pkg 构建流程图

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

这个问题一般来说有两个回答:

  • ① 在 Ports 中的确没有这个 Port:书里写错了、从 Ports 中移除了/改名了等

  • ② Ports 中的确有这个 Port:FreeBSD 的 pkg 包是周期性构建的(因为 Ports 本身在更新),会经常存在没有特定 pkg 包存在的情况

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

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

一般来说,如果 Ports 中有这个 Port,但是 pkg 安装没有,等待 7-14 天一般就可以了(构建不出来的包系统会自动发报错给维护者的)。如要立刻安装使用,请使用 Ports。

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

你会经常观察到 FreeBSD 的镜像站(无论是官方的还是非官方的)源存在这样几种情况:

  • 一旦 Port 发生更新,就会立刻从软件源撤销该 Port 衍生的 pkg 软件包,直到下次构建出新的 pkg 软件包,而不是保留旧的软件包;

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

理论上的解决方案:如果你保持一个特定阶段的软件包不更新,是固定版本(季度分支),然后直接轮替即可。

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

思考题

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

安装 pkg 包管理器本体

技巧

根据 man pkg(7) 页面解释:

为了避免出现向后兼容问题,实际的 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 Packages

你会发现 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?

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

问题示例:

问题在于数据库未同步。

刷新数据库:

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

出现该问题一般是由于 ABI 破坏,更新即可。

安装 bsdadminscripts2

或者

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

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

  • BSD Administration Scripts II,项目地址,含详细使用说明

  • 若使用了 pkgbase,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"

最后更新于

这有帮助吗?