第四章 安装应用:Packages和Ports

第四章 安装应用:Packages和Ports4.1. 简介4.2. 软件安装概述4.3. 寻找软件4.4. 使用 pkg 进行二进制包管理4.4.1. pkg 入门4.4.2. 季度和最新 Ports 分支4.4.3. 内核模块存储库4.4.4. 配置 pkg4.4.5. 搜索软件包4.4.6. 安装和获取软件包4.4.7. 获取已安装软件包的信息4.4.8. 升级已安装的软件包4.4.9. 审核已安装的软件包4.4.10. 删除程序包4.4.11. 自动删除未使用的包4.4.12. 删除过期包4.4.13. 锁定和解锁包裹4.4.14. 修改包元数据4.5. 使用Ports集合4.5.1. 安装 Ports 集合过程:Git方法4.5.2. 安装Ports4.5.2.1. 自定义Ports安装4.5.3. 删除安装的Ports4.5.4. 升级Ports4.5.4.1. 升级和管理Ports的工具4.5.4.2. 使用Portmaster升级Ports4.5.4.3. 使用Portupgrade升级Ports4.5.5. Ports和磁盘空间4.6. 使用 poudriere 构建包4.6.1. 初始化Jails和Port Trees4.6.2. 配置 pkg 客户端以使用 poudriere 存储库4.7. 安装后注意事项4.8. 处理损坏的Ports

4.1. 简介

FreeBSD与丰富的系统工具集捆绑在一起,作为基础系统的一部分。此外,FreeBSD提供了两种互补的技术来安装第三方软件:

任何一种方法都可以用于从本地媒体或网络安装软件。

阅读本章以了解:

4.2. 软件安装概述

FreeBSD port 是一组文件,旨在自动化从源代码编译应用程序的过程。组成port的文件包含自动下载、提取、修补、编译和安装应用程序所需的所有信息。

如果软件尚未在FreeBSD上进行改编和测试,则可能需要编辑源代码才能正确安装和运行。

然而,已有超过36000个第三方应用程序被移植到FreeBSD。在可行的情况下,这些应用程序可以作为预编译包下载。

可以使用FreeBSD包管理命令操纵包。

packages和ports都理解依赖关系。如果使用包或port安装应用程序,但尚未安装依赖库,则将首先自动安装该库。

FreeBSD包包含应用程序所有命令的预编译副本,以及任何配置文件和文档。可以使用 pkg(8) 命令操纵包,例如 pkg install

虽然这两种技术相似,但packages和ports各有其优势。选择满足安装特定应用程序需求的技术。

要跟踪更新的ports,请订阅 FreeBSD ports 邮件列表FreeBSD ports 错误邮件列表

本章的其余部分解释了如何使用 packages 和 ports 在FreeBSD上安装和管理第三方软件。

4.3. 寻找软件

FreeBSD的可用应用程序列表一直在增长。有多种方法可以找到要安装的软件:

4.4. 使用 pkg 进行二进制包管理

pkg(8) 提供了一个操作包的接口:注册(registering,)、添加(adding,)、删除(removing)和升级(upgrading)包。

对于希望只使用FreeBSD镜像中的预构建二进制包的网站,使用 pkg(8) 管理包就足够了。

然而,对于那些从源头构建的站点,将需要一个单独的 port 管理工具。

由于 pkg(8) 仅适用于二进制包,因此它不能替代此类工具。这些工具可用于从二进制包和Ports Collection安装软件,而 pkg(8) 只安装二进制包。

4.4.1. pkg 入门

所有受支持的FreeBSD版本现在都包含 /usr/sbin/pkg a.k.a pkg(7) 。这是一个小占位符,仅具有安装真正 pkg(8) 所需的最低功能。

运行 pkg(8) 命令行:

pkg(7) 将拦截该命令,并在确认后下载 pkg(8) tarball,从中安装 pkg(8) ,引导本地包数据库,然后继续运行最初请求的命令。

最新版本的 pkg(7)pkg -N 理解为一种测试,用于查看是否在不触发安装的情况下安装了 pkg(8) ,相反,pkg 引导 [-f] 安装 pkg(8) (或强制重新安装),而不执行任何其他操作。

pkg的使用信息可以在 pkg(8) 手册页中找到,也可以在不带其他参数的情况下运行 pkgpkg.conf(5) 中描述了其他 pkg 配置选项。

每个 pkg 命令参数都记录在特定于命令的手册页中。

例如,要阅读pkg安装的手册页,请运行以下命令:

本节的其余部分演示了可以使用 pkg(8) 执行的常见二进制包管理任务。每个演示的命令都提供了许多开关来定制其使用。有关详细信息和更多示例,请参阅命令的帮助或手册页。

4.4.2. 季度和最新 Ports 分支

Quarterly 分支为用户提供了更可预测和稳定的port和软件包安装和升级体验。这基本上是通过只允许非功能更新来实现的。季度分支旨在接收安全修复(可能是版本更新或提交的后端口(backports))、错误修复和ports合规性(compliance)或框架更改。在1月、4月、7月和10月的每个(年度)季度开始时,从HEAD中删除季度分支。分支根据创建年份(YYYY)和季度(Q1-4)命名。例如,2023年1月创建的季度分支命名为2023Q1。Latest 分支向用户提供包的最新版本。

要将 pkg(8)Quarterly 切换到 Latest ,请运行以下命令:

然后运行此命令以更新Latest分支的本地包存储库目录:

4.4.3. 内核模块存储库

内核模块存储库允许用户安装即用型内核模块(ready to use kernel modules),如用于图形驱动程序和特定硬件的模块。从FreeBSD 14.3开始,FreeBSD项目提供了为每个支持的版本构建的内核模块。如果不存在这样的存储库配置,要创建它,请将以下内容添加到 /usr/local/etc/pkg/repos/kmods.conf

KMODSFLAVOR 遵循以下模式:kmods_PORTBRANC_MINORRELEASE

例如:

表7. Kmodsflavor

FreeBSD发行版ports mainports quarterly
FreeBSD 14.2-RELEASEkmods_latest_2kmods_quarterly_2
FreeBSD 14.3-RELEASEkmods_latest_3kmods_quarterly_3
FreeBSD 14.3-STABLEkmods_latestkmods_quarterly
FreeBSD 15.0-CURRENTkmods_latest 

4.4.4. 配置 pkg

pkg.conf(5)pkg(8) 工具使用的系统范围配置文件。此文件的默认位置是 /usr/local/etc/pkg.conf

文件中以 # 开头的行是注释,将被忽略。

该文件为UCL(Universal Configuration Language,通用配置语言)格式。有关 libucl(3) 语法的更多信息,请访问 UCL官方网站

可以识别以下类型的选项:布尔、字符串和列表选项。

如果在配置文件中指定了以下值之一: YESTRUEON ,则布尔选项标记为启用。

4.4.5. 搜索软件包

要搜索软件包,可以使用 pkg-search(8)

4.4.6. 安装和获取软件包

要安装二进制软件包,可以使用 pkg-install(8) 。此命令使用存储库数据来确定要安装哪个版本的软件,以及它是否有任何未安装的依赖项。例如,要安装 curl

新包和作为依赖项安装的任何其他包都可以在已安装包列表中看到:

要获取软件包并在以后或其他地方安装,请使用 pkg-fetch(8) 。例如,要下载 nginx-lite

输出应类似于以下内容:

要安装下载的软件包,可以按如下方式使用 pkg-install(8)

4.4.7. 获取已安装软件包的信息

通过运行 pkg-info(8) 可以查看系统上安装的软件包的信息,当不使用任何开关运行时,它将列出所有已安装软件包或指定软件包的软件包版本。

例如,要查看安装了哪个版本的pkg,请运行:

4.4.8. 升级已安装的软件包

已安装的软件包可以使用 pkg-upgrade(8) 升级到最新版本:

此命令将把已安装的版本与存储库目录中的可用版本进行比较,并从存储库中升级它们。

4.4.9. 审核已安装的软件包

第三方应用程序中经常发现软件漏洞。为了解决这个问题,pkg包括一个内置的审计机制。要确定系统上安装的软件是否存在任何已知漏洞,请使用 pkg-audit(8)

4.4.10. 删除程序包

不再需要的包可以通过 pkg-delete(8) 删除。

例如:

4.4.11. 自动删除未使用的包

删除包可能会留下不再需要的依赖关系。作为依赖项安装的不需要的包(叶子包)可以使用 pkg-autoremove(8) 自动检测和删除:

作为依赖项安装的包称为自动 包。非自动软件包,即明确安装的不依赖于另一个软件包的软件包,可以使用以下方式列出:

pkg prime-list/usr/local/etc/pkg.conf 中声明的别名命令。还有许多其他命令可用于查询系统的包数据库。例如,可以使用命令 pkg prime-origins 来获取上述列表的origin-port目录:

此列表可用于使用 portsmgmt/poudriereports-mgmt/synth 等构建工具重建系统上安装的所有软件包。

可以使用以下命令将已安装的软件包标记为自动:

一旦一个包是叶子包并标记为自动,它就会被 pkg autoremove 选中。

可以使用以下命令将已安装的软件包标记为非自动:

4.4.12. 删除过期包

默认情况下,pkg将二进制包存储在 pkg.conf(5)PKG_CACHEDIR 定义的缓存目录中。仅保留最新安装的软件包的副本。旧版本的pkg保留了所有以前的包。要删除这些过时的二进制包,请运行:

可以通过运行以下命令清除整个缓存:

4.4.13. 锁定和解锁包裹

pkg-lock(8) 用于锁定软件包,防止重新安装、修改或删除。 pkg-unlock(8) 解锁指定的包。任何一种变体都只对当前安装的软件包有影响。因此,不可能使用此机制阻止新包的安装,除非这种安装意味着更新锁定的包。

例如,要锁定 nginx-lite

要解锁 nginx-lite

4.4.14. 修改包元数据

FreeBSD Ports Collection中的软件可能会发生重大版本号更改。为了解决这个问题,pkg有一个内置的命令来更新包源代码。例如,如果将 lang/python3 重命名为 lang/pythong311 ,那么 lang/pythone3 现在可以表示3.11版本,这可能很有用。

要更改上述示例的包源,请运行:

再举一个例子,要将 lang/ruby31 更新为 lang/ruby22 ,请运行:

4.5. 使用Ports集合

Ports Collection是一组 Makefile 、补丁和描述文件。每组文件都用于在FreeBSD上编译和安装单个应用程序,称为 port

默认情况下,Ports Collection本身存储在 /usr/Ports 的子目录中。

Ports Collection包含软件类别的目录。每个类别中都有单独应用程序的子目录。每个应用程序子目录都包含一组文件,告诉FreeBSD如何编译和安装该程序,称为 ports skeleton (骨架)。每个 ports 骨架都包含以下文件和目录:

一些 ports 包含 pkg-message 或其他文件来处理特殊情况。有关这些文件以及一般 ports 的更多详细信息,请参阅 FreeBSD Porter手册

该 ports 不包括实际的源代码,也称为 distfile 。构建 ports 的提取部分会自动将下载的源代码保存到 /usr/ports/distfiles

4.5.1. 安装 Ports 集合

在使用 port 编译应用程序之前,必须首先安装 Ports Collection 。如果在FreeBSD安装过程中没有安装,请使用以下方法进行安装:

过程:Git方法

如果需要对ports tree进行更多控制,或者需要维护本地更改,或者如果运行FreeBSD CURRENT,可以使用Git获取Ports集合。有关Git的详细说明,请参阅 Git入门

我们在 git 命令行中添加 --depth 1 来克隆树,而无需获取提交历史记录,这节省了时间,并且大多数用户都可以接受。在维护对 ports tree 的自定义更改时,或者出于任何原因需要历史记录时,请省略下面的 --depth 1 参数。

  1. 必须先安装Git,然后才能用于签出ports tree。如果ports tree的副本已经存在,请按如下方式安装Git:

    如果ports树不可用,或者使用pkg管理包,Git可以作为包安装:

  2. 查看ports树的HEAD分支的副本:

  3. 或者,查看一份季度分支机构的副本:

  4. 根据需要,在初始Git签出后更新 /usr/ports

  5. 根据需要,将 /usr/ports 切换到不同的季度分支:

4.5.2. 安装Ports

本节提供有关使用Ports集合安装或删除软件的基本说明。 ports(7) 中提供了可用 make 目标和环境变量的详细描述。

使用Ports集合假定Internet连接正常。它还需要超级用户权限。

要编译和安装端口,请切换到要安装的端口的目录,然后在提示符下键入 make install 。消息将指示进度:

由于 lsof 是一个以更高权限运行的程序,因此在安装时会显示安全警告。安装完成后,将返回提示。

一些shell保留了 PATH 环境变量中列出的目录中可用的命令的缓存,以加快对这些命令的可执行文件的查找操作。tcsh shell的用户应键入 rehash ,以便可以使用新安装的命令,而无需指定其完整路径。使用 hash -r 代替 sh shell。有关更多信息,请参阅shell的文档。

在安装过程中,会创建一个工作子目录,其中包含编译过程中使用的所有临时文件。删除此目录可以节省磁盘空间,并最大限度地减少以后升级到较新版本的Ports时出现问题的可能性:

4.5.2.1. 自定义Ports安装

一些ports提供构建选项,可用于启用或禁用应用程序组件、提供安全选项或允许其他自定义。示例包括 www/firefoxsecurity/gpgme 。如果port依赖于具有可配置选项的其他port,它可能会暂停几次以进行用户交互,因为默认行为是提示用户从菜单中选择选项。为了避免这种情况并一次性完成所有配置,请在port骨架内运行 make config-recursive 。然后,运行 make install [clean] 编译并安装port。

有几种方法可以重新访问port的构建选项菜单,以便在构建port后添加、删除或更改这些选项。一种方法是 cd 到包含port的目录中,然后键入 make config 。另一种选择是使用 make showconfig 。另一种选择是执行 make rmconfig ,这将删除所有选定的选项并允许重新开始。所有这些选项和其他选项在 ports(7) 中都有详细解释。

ports系统使用 fetch(1) 下载支持各种环境变量的源文件。如果FreeBSD系统位于防火墙或FTP/HTTP代理之后,则可能需要设置 FTP_PASSIVE_MODEFTP_PROXYFTP_PASSWORD 变量。有关支持变量的完整列表,请参阅 fetch(3)

对于无法始终连接到Internet的用户, make fetch 可以在 /usr/ports 中运行,以获取所有distfiles,或者在 /usr/ports/net 等类别中运行,或者在特定的port骨架中运行。请注意,如果一个port有任何依赖关系,在类别或port骨架中运行此命令将不会从另一个类别中获取port的distfile。相反,使用 make fetch-recursive 也可以获取port所有依赖项的distfiles。

在极少数情况下,例如当一个组织拥有本地distfiles存储库时,MASTER_SITES 变量可用于覆盖 Makefile 中指定的下载位置。使用时,指定备用位置:

WRKDIRPREFIXPREFIX 变量可以覆盖默认的工作目录和目标目录。例如:

将编译 /usr/home/example/ports 中的port,并在/usr/local下安装所有内容。

将编译 /usr/ports 中的port,并将其安装在 /usr/home/example/local 中。以及:

将两者结合起来。

这些也可以设置为环境变量。有关如何设置环境变量的说明,请参阅shell的手册页。

4.5.3. 删除安装的Ports

可以使用 pkg-delete 卸载已安装的ports。使用此命令的示例可以在 pkg-delete(8) 手册页中找到。

或者,可以在port的目录中运行 make deinstall

建议在卸载port时阅读消息。如果该port有任何依赖于它的应用程序,则会显示此信息,但卸载将继续。在这种情况下,最好重新安装应用程序,以防止破坏依赖关系。

4.5.4. 升级Ports

随着时间的推移,Ports Collection中会提供更新版本的软件。本节介绍如何确定哪些软件可以升级以及如何执行升级。

要确定已安装port的较新版本是否可用,请使用Git方法中描述的更新命令确保安装了最新版本的port树。以下命令将列出过期的已安装port:

4.5.4.1. 升级和管理Ports的工具

Ports Collection包含几个用于执行实际升级的实用程序。每个实用程序都有自己的长处和短处。

从历史上看,大多数安装都使用Portmaster或Portupgrade。Synth是一种较新的替代品。

4.5.4.2. 使用Portmaster升级Ports

ports-mgmt/portmaster 是一个用于升级已安装ports的非常小的实用程序。它旨在使用FreeBSD基础系统安装的工具,而不依赖于其他ports或数据库。要将此实用程序作为ports安装,请执行以下操作:

Portmaster定义了四类ports:

要列出这些类别并搜索更新:

此命令用于升级所有过时的ports:

如果在升级过程中遇到错误,请添加 -f 以升级和重建所有ports:

Portmaster还可以用于在系统上安装新ports,在构建和安装新ports之前升级所有依赖项。要使用此功能,请在ports集合中指定ports的位置:

有关 ports-mgmt/portmaster 的更多信息,请参阅其 pkg-descr

4.5.4.3. 使用Portupgrade升级Ports

ports-mgmt/portupgrade 是另一个可用于升级ports的实用程序。它安装了一套可用于管理ports的应用程序。然而,它依赖于Ruby。要安装port,请执行以下操作:

在使用此实用程序执行升级之前,建议使用 pkgdb -F 扫描已安装ports的列表,并修复它报告的所有不一致。

要升级系统上安装的所有过时ports,请使用 portupgrade -a 。或者,在每次单独升级时都会要求包括 -i

要仅升级指定的应用程序而不是所有可用ports,请使用 portupgrade pkgname 。包含 -R 以首先升级给定应用程序所需的所有ports非常重要:

如果包含 -P ,Portupgrade将在 PKG_PATH 中列出的本地目录中搜索可用包。如果本地没有可用的包,则从远程站点获取包。如果无法在本地找到或远程获取包,Portupgrade将使用ports。若要避免完全使用ports,请指定 -PP 。最后一组选项告诉Portupgrade在没有可用包的情况下中止:

要只获取port distfiles或包(如果指定了 -P ),而不构建或安装任何东西,请使用 -F 。有关所有可用交换机的更多信息,请参阅 portupgrade 的手册页。

有关port mgmt/portupgrade 的更多信息,请参阅其 pkg-descr

4.5.5. Ports和磁盘空间

随着时间的推移,使用Ports集合将耗尽磁盘空间。在构建和安装port后,在port骨架中运行 make clean 将清理临时 work 目录。如果使用 Portmaster 安装port,除非指定 -K ,否则它将自动删除此目录。如果安装了 Portupgrade ,此命令将删除在Ports Collection的本地副本中找到的所有 work 目录:

此外,随着时间的推移,过时的源代码分发文件会累积在 /usr/ports/distfiles 中。要使用 Portupgrade 删除任何port不再引用的所有distfile,请执行以下操作:

port升级可以删除系统上当前安装的任何port未引用的所有distfiles:

如果安装了 Portmaster ,请使用:

默认情况下,此命令是交互式的,会提示用户确认是否应删除distfile。

除了这些命令, ports-mgmt/pkg_cutleaves 还会自动删除不再需要的已安装ports。

4.6. 使用 poudriere 构建包

poudriere 是一个BSD许可的实用程序,用于创建和测试FreeBSD包。它使用FreeBSD jails来设置隔离的编译环境。这些jail可用于为与安装它的系统不同的FreeBSD版本构建包,如果主机是amd64系统,还可以为i386构建包。一旦构建了包,它们的布局与官方镜像完全相同。pkg(8) 和其他包管理工具可以使用这些包。

poudriere 是使用 ports-mgmt/pudriere 软件包或port安装的。安装包括一个示例配置文件 /usr/local/etc/poudriere.conf.sample 。将此文件复制到 /usr/local/etc/poudriere.conf 。编辑复制的文件以适应本地配置。

虽然运行浇注机的系统不需要 ZFS ,但它是有益的。使用 ZFS 时,必须在 /usr/local/etc/poudriere.conf 中指定 ZPOOL ,并将 FREEBSD_HOST 设置为附近的镜像。定义 CCACHE_DIR 允许使用 devel/ccache 来缓存编译,并减少频繁编译代码的构建时间。将 poudrier 数据集放在安装在 /poudriere 的孤立树中可能很方便。其他配置值的默认值就足够了。

检测到的处理器内核数量用于定义并行运行的构建数量。提供足够的虚拟内存,包括 RAM 或交换空间。如果虚拟内存用完,编译jail将停止并被拆除,从而导致奇怪的错误消息。

4.6.1. 初始化Jails和Port Trees

配置后,初始化 poudriere ,以便它安装一个具有所需FreeBSD树和ports树的jail。使用 -j 指定jail的名称,使用 -v 指定FreeBSD版本。在运行FreeBSD/amd64的系统上,可以使用 -a 将架构设置为i386或amd64。默认是 uname 显示的架构。

在一台计算机上,poudrier 可以在多个jails和不同的port树中构建具有多种配置的port。这些组合的自定义配置称为集合。安装port mgmt/pudriereportsmgmt/poudriere-devel 后,有关详细信息,请参阅 poudriere(8) 的自定义部分。

这里显示的基本配置在 /usr/local/etc/poudriere.d 中放置了一个单独的 jail-port-set-specific 特定的 make.conf 。本例中的文件名是通过组合jail名称、port名称和set名称创建的:13amd64-local-workstation-make.conf 。系统 make.conf 和这个新文件在构建时组合在一起,以创建构建jail使用的 make.conf

要构建的包在 13amd64-local-workstation-pkglist 中输入(带有 FLAVORS 的ports可以用 @FLAVOR 定义):

已配置指定ports的选项和依赖关系:

最后,构建包并创建包存储库:

运行时,按 Ctrl+t 显示构建的当前状态。 poudriere 还在 /poudriere/logs/bulk/jailname 中构建文件,这些文件可以与web服务器一起使用,以显示构建信息。

完成后,新软件包现在可以从poudriere存储库进行安装。

有关使用poudriere的更多信息,请参阅 poudriere(8) 和主网站,https://github.com/freebsd/poudriere/wiki

4.6.2. 配置 pkg 客户端以使用 poudriere 存储库

虽然可以在官方存储库的同时使用自定义存储库,但有时禁用官方存储库是有用的。这是通过创建一个覆盖和禁用官方配置文件的配置文件来实现的。创建 /usr/local/etc/pkg/repos/FreeBSD.conf ,其中包含以下内容:

通常,通过HTTP向客户端机器提供poudriere存储库是最简单的。设置一个Web服务器来提供包目录,例如:/usr/local/poudriere/data/packages/13amd64 ,其中 13amd64 是构建的名称。

如果包存储库的URL为:http://pkg.example.com/13amd64,那么 /usr/local/etc/pkg/repos/custom.conf 中的存储库配置文件如下:

如果不希望将包存储库暴露在互联网上,可以使用 file:// 协议直接指向存储库:

4.7. 安装后注意事项

无论软件是从二进制包还是ports安装的,大多数第三方应用程序在安装后都需要一定程度的配置。以下命令和位置可用于帮助确定应用程序安装了什么。

4.8. 处理损坏的Ports

当port未构建或安装时,请尝试以下操作:

  1. 问题报告数据库 中搜索该port是否有待处理的修复程序。如果是这样,实施拟议的修复可能会解决这个问题。

  2. 向port维护人员寻求帮助。在ports骨架中键入 make maintainer ,或读取ports的 Makefile 以查找维护者的电子邮件地址。记得在给维护人员的电子邮件中包含导致错误的输出。

    如果电子邮件没有回复,请使用Bugzilla按照 编写FreeBSD问题报告 中的说明提交错误报告。

  3. 修好它!Porter's手册 包括有关ports基础设施的详细信息,可以修复偶尔损坏的ports或提交新的ports。使用 【4.4. 使用pkg进行二进制包管理】中的说明安装软件包而不是port。