---
title: "第 5 章 安装应用程序: Packages 和 Ports"
part: 部分 I. 起步
prev: books/handbook/basics
next: books/handbook/x11
showBookMenu: true
weight: 7
params:
  path: "/books/handbook/ports/"
---

[[ports]]
= 安装应用程序: Packages 和 Ports
:doctype: book
:toc: macro
:toclevels: 1
:icons: font
:sectnums:
:sectnumlevels: 6
:sectnumoffset: 5
:partnums:
:source-highlighter: rouge
:experimental:
:images-path: books/handbook/ports/

ifdef::env-beastie[]
ifdef::backend-html5[]
:imagesdir: ../../../../images/{images-path}
endif::[]
ifndef::book[]
include::shared/authors.adoc[]
include::shared/mirrors.adoc[]
include::shared/releases.adoc[]
include::shared/attributes/attributes-{{% lang %}}.adoc[]
include::shared/{{% lang %}}/teams.adoc[]
include::shared/{{% lang %}}/mailing-lists.adoc[]
include::shared/{{% lang %}}/urls.adoc[]
toc::[]
endif::[]
ifdef::backend-pdf,backend-epub3[]
include::../../../../../shared/asciidoctor.adoc[]
endif::[]
endif::[]

ifndef::env-beastie[]
toc::[]
include::../../../../../shared/asciidoctor.adoc[]
endif::[]

[[ports-synopsis]]
== 概述

FreeBSD 将许多系统工具捆绑作为基本系统的一部分。 然而， 要完成实际的工作， 可能还需要安装更多的第三方应用。 FreeBSD 提供了两种补充的技术， 用以在您的系统中安装第三方软件： FreeBSD Ports 套件 (用于从源代码安装)， 以及 packages (用以从预编译的二进制版本安装)。 这两种方法都可以用于从本地介质， 或从网上直接安装您喜欢的应用程序的最新版本。

读完这章，您将了解到:

* 如何安装第三方的二进制软件包。
* 如何使用 ports 套件从源代码构建第三方软件。
* 如何删除先前安装的软件包。
* 如何改动Ports Collection里面的一些参数，定制软件使用。
* 如何找到您需要的软件包。
* 如何升级您的应用软件。

[[ports-overview]]
== 软件安装预览

如果您以前使用过 UNIX(R) 系统，那典型的第三方软件安装的步骤是像下面描述的：

[.procedure]
====
. 下载这个软件，软件的发行版可能是源代码格式，或是一个二进制包。
. 解开软件(其中代表性的是用 man:compress[1], man:gzip[1], 或 man:bzip2[1] 压缩过的tar包)。
. 阅读相关文档，了解如何安装。 (多半一个文件名是[.filename]##INSTALL##或[.filename]##README##， 或在[.filename]##doc/## 目录下的一些文档)
. 如果软件是以源代码形式发布的，那就需要编译它。可能需要编辑一个 [.filename]##Makefile##文件, 或运行 ``configure``脚本，和其他的一些工作。
. 测试和安装软件。
====

如果一切顺利的话，就这么简单。如果您在安装一个软件包时发生一些错误， 您可能需要编辑一下它的代码，以使它能正常工作。

您可以继续使用 "传统的"方式安装软件。 然而， FreeBSD 提供了两种技术： packages 和 ports。 就在写这篇文章的时候， 已经有超过 {numports} 个第三方的应用程序可以使用了。

对于任意一个应用程序包，是一个可以下载的FreeBSD package文件。这个 FreeBSD package包含了编译好的的副本， 还有一些配置文件或文档。 一个下载的包文件可以用 FreeBSD 的包管理命令来操作， 例如 man:pkg_add[1]，man:pkg_delete[1], man:pkg_info[1] 等等。 可以使用一个简单的命令安装一个新的应用程序。

一个FreeBSD的port是一个可以自动从源代码编译成应用程序的文件集合。

记住，如果您自己来编译的话，需要执行很多步的操作 (解压， 补丁， 编译， 安装)。 这些整理 port 的文件集合包含了系统需要完成这个工作的必需信息。 您可以运行一些简单的命令， 那些源代码就可以自动地下载， 解开， 打补丁， 编译， 直至安装完成。

实际上，ports 系统也能做出被 `pkg_add` 的程序包和不久就要讲到的其他包管理命令来安装的软件包。

Packages 和 ports 是互相 _依赖_ 的。 假设您想安装一个依赖于已经安装的特定库的应用程序。 应用程序和那个库都已经应用于 FreeBSD ports 和 packages。 如果您使用 命令或 ports 系统来添加应用程序， 两个都必须注意库是否被安装， 如果没有， 它会自动先安装库。

这里给出的两种技术是很相似的，您可能会奇怪为什么 FreeBSD 会弄出这两种技术。 其实， packages 和 ports 都有它们自己的长处， 使用哪一种完全取决于您自己的喜好。

.Package Benefits
* 一个压缩的 package 通常要比一个压缩的包含源代码的应用程序小得多。
* package 不需要进行额外的编译。 对于大型应用程序如 Mozilla， KDE 或 GNOME 来说这显得尤为重要， 特别是在您的系统资源比较差的情况下。
* package不需要您知道如何在FreeBSD上编译软件的详细过程。

.Ports Benefits
* package 在编译时通常使用比较保守的选项， 这是为了保证它们能够运行在大多数的系统上。 通过从 port 安装， 您可以细微调整编译选项来产生适合于处理器的代码 (针对于 Pentium 4 或 AMD 的 Athlon CPU)。
* 一些软件包已经把与它们相关的能做和不能做的事情的选项都编译进去了。 例如， Apache 可能就配置了很多的选项。 从 port 中安装时， 您不一定要接受默认的选项， 可以自己来设置。
+ 
在一些例子中，一个软件有不同的配置存在多个package。 例如， Ghostscript存在 [.filename]#ghostscript# package 和 [.filename]#ghostscript-nox11# package两个配置package， 这取决于您是否安装了X11服务器。 这样的调整对package是可能的， 但如果一个应用程序有超过一个或两个不同的编译时间选项时， 就不行了。
* 一些软件的许可条件禁止采用二进制形式发行。 它们必须带上源代码。
* 一些人不信任二进制发行形式。 至少有了源代码， (理论上) 可以亲自阅读它，寻找潜在的问题。
* 如果您要自己对软件打补丁，您就需要有源代码。
* 一些人喜欢整天围着源代码转， 所以他们喜欢亲自阅读源代码， 修改源代码等等。

保持更新 ports， 订阅邮件列表 {freebsd-ports} 和递交错误报告 {freebsd-ports-bugs}。

[WARNING]
====

安装任何应用程序之前， 应首先检查 http://vuxml.freebsd.org/[http://vuxml.freebsd.org/] 上是否有关于您所安装的应用程序的安全问题报告。

您也可以安装 package:ports-mgmt/portaudit[]， 它能够自动地检查已经安装的应用程序的漏洞； 此外， 在您安装程序之前它也会首先检查是否存在已知的漏洞。 另外， 您也可以使用 `portaudit -F -a` 这个命令在安装了某个软件包之后作出检查。
====

这章的其余部分将介绍在 FreeBSD 上如何使用 packages 和 ports 来安装和管理第三方软件。

[[ports-finding-applications]]
== 寻找您要的应用程序

在您安装任何应用程序之前，需要知道您需要什么，那个应用程序叫什么。

FreeBSD中可用的应用程序正在不断地增长着。幸运的是， 有许多方法可以找到您所需要的程序:

* FreeBSD站点上有一个可以搜索到的当前所有可用的应用程序列表，在 link:https://www.FreeBSD.org/ports/[http://www.FreeBSD.org/ports/]。 它分很多种类，您既可以通过程序的名称来搜索(如果您知道名字)， 也可以在分类中列出所有可用的应用程序。
* Dan Langille 维护着网站 FreshPorts，在 http://www.FreshPorts.org/[http://www.FreshPorts.org/]。 FreshPort时刻 "追踪" 着在 ports 中应用程序的变化。当有任何程序被升级时，他们就会发 email 提醒您。
* 如果您不知道您想要的应用程序的名字，可以通过 (http://www.freshmeat.net/[http://www.freshmeat.net/]) 网站来查找， 如果找到了应用程序， 您可以回 FreeBSD 的主站去看一下这个应用程序是否已经被 port 进去了。 
* 如果您知道一个port的准确名字， 但需要知道在哪个类别里面能找到它，您可以使用 man:whereis[1] 这个命令。简单地输入 `whereis file`， _file_ 就是您想安装的程序名字。 如果系统找到了它， 您将被告知在它在哪里， 例如:
+
[source,shell]
....
# whereis lsof
lsof: /usr/ports/sysutils/lsof
....
+ 
结果告诉我们这个命令``lsof`` (一个系统配置程序)可以在 [.filename]##/usr/ports/sysutils/lsof##目录中找到。
* 你可以使用简单的 man:echo[1] 语句来查找某个 port 是否存在于 ports 树中。 例如：
+
[source,shell]
....
# echo /usr/ports/*/*lsof*
/usr/ports/sysutils/lsof
....
+ 
Note that this will return any matched files downloaded into the [.filename]#/usr/ports/distfiles# directory.
+ 
请注意这条命令将会返回下载到 [.filename]#/usr/ports/distfiles# 目录中所有符合条件的文件。
* 还有另外的一个寻找您需要的port的方法--是用ports collecton 内嵌的搜索机制。要使用这个搜索, 您需要先到 [.filename]##/usr/ports##目录下面。 在那个目录里面， 运行``make search name=program-name``， __program-name__ 就是您想寻找的程序名字。 举个例子， 如果您想找 `lsof`：
+
[source,shell]
....
# cd /usr/ports
# make search name=lsof
Port:   lsof-4.56.4
Path:   /usr/ports/sysutils/lsof
Info:   Lists information about open files (similar to fstat(1))
Maint:  obrien@FreeBSD.org
Index:  sysutils
B-deps:
R-deps: 
....
+ 
在输出的内容里面您要特别注意包含 "Path:" 的这行将告诉您在哪里可以找到这个 port。 如果要安装此 port， 那其他输出的信息不是必须的， 但是还是显示输出了。
+ 
为了更深入的搜索，您还可以用 `make search key=string`， __string__就是您想搜索的部分内容。 它将搜索port的名字、 注释， 描述和从属关系， 如果您不知道您想搜索的程序名字， 可以利用它搜索一些关键主题来找到您需要的。
+ 
上面说的这些方法， 搜索的关键字没有大小写区分的。 搜索 "LSOF"的结果将和搜索"lsof"的结果一样。

[[packages-using]]
== 使用 Package 系统

在 FreeBSD 系统上有几种不同的工具用来管理 package：

* `sysinstall` 工具可以在正在运行的系统上运行， 以完成安装、 删除和列出可用的以及已经安装的预编译软件包的任务。 如欲了解进一步信息， 请参阅 crossref:install[packages,安装预编译的软件包 (package)]。
* 这一节余下的部分将介绍用于管理预编译软件包的命令行工具。

=== 一个 package 的安装

您可以用 man:pkg_add[1] 这个命令从本地文件或网络上的服务器来安装一个 FreeBSD 软件包。

.在本地手动下载一个package,并安装它
[example]
====

[source,shell]
....
# ftp -a ftp2.FreeBSD.org
Connected to ftp2.FreeBSD.org.
220 ftp2.FreeBSD.org FTP server (Version 6.00LS) ready.
331 Guest login ok, send your email address as password.
230-
230-     This machine is in Vienna, VA, USA, hosted by Verio.
230-         Questions? E-mail freebsd@vienna.verio.net.
230-
230-
230 Guest login ok, access restrictions apply.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> cd /pub/FreeBSD/ports/packages/sysutils/
250 CWD command successful.
ftp> get lsof-4.56.4.tgz
local: lsof-4.56.4.tgz remote: lsof-4.56.4.tgz
200 PORT command successful.
150 Opening BINARY mode data connection for 'lsof-4.56.4.tgz' (92375 bytes).
100% |**************************************************| 92375       00:00 ETA
226 Transfer complete.
92375 bytes received in 5.60 seconds (16.11 KB/s)
ftp> exit
# pkg_add lsof-4.56.4.tgz
....

====

如果您没有本地package的安装盘 (如 FreeBSD CD-ROM)， 可以执行 man:pkg_add[1] 命令并加上 `-r` 选项。 这将迫使程序自动决定目标文件的正确格式和版本， 然后自动从一个 FTP 站点寻找和安装 package。

[source,shell]
....
# pkg_add -r lsof
....

上面的例子将下载正确的package， 而不需要用户的干预就可以安装。 如果您想指定 FreeBSD package 的镜像站点， 替换主站点， 就必须相应地设置 `PACKAGESITE` 这个环境变量， 覆盖原来的设置。 man:pkg_add[1] 使用 man:fetch[3] 下载文件， 可以使用多种环境变量， 包含 `FTP_PASSIVE_MODE`、 `FTP_PROXY`， 和 `FTP_PASSWORD`。 如果您使用 FTP/HTTP 代理或在防火墙后面， 您可能需要设置这些环境变量。 详细的列表请参考 man:fetch[3]。上述例子中用 `lsof` 替代了 `lsof-4.56.4`。 当使用远程安装 Package 的时候软件名字不需要包含版本号。 man:pkg_add[1] 将自动的找到这个软件最新的版本。

[NOTE]
====
如果您使用 FreeBSD-CURRENT 或 FreeBSD-STABLE版本的FreeBSD， man:pkg_add[1] 将下载您的应用软件的最新版本。 如果您使用 -RELEASE 版本的 FreeBSD, 它将会获得与您的版本相应的软件包版本。 您可以通过修改环境变量 `PACKAGESITE` 来改变这一行为。 例如， 如果您运行 FreeBSD 8.1-RELEASE 系统， 默认情况下 man:pkg_add[1] 将尝试从 `ftp://ftp.freebsd.org/pub/FreeBSD/ports/i386/packages-8.1-release/Latest/` 下载预编译的软件包。 如果您希望强制 man:pkg_add[1] 下载 FreeBSD 8-STABLE 的软件包， 则可以将 `PACKAGESITE` 设置为 `ftp://ftp.freebsd.org/pub/FreeBSD/ports/i386/packages-8-stable/Latest/`。 
====

软件包采用 [.filename]#.tgz# 和 [.filename]#.tbz# 两种格式。您可以在 link:ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/packages/[ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/packages/] 下面或从 FreeBSD 的发行光盘找到， 它在每一个 4CD 的 FreeBSD 发行版的 [.filename]##/packages##目录中。 软件包的设计规划与 [.filename]#/usr/ports# 树一致。 每个分类都有自己的目录， 所有的软件包可以在目录 [.filename]##All##中找到。 

软件包系统的目录结构与ports的设计规划一致； 它们共同构成了整个 package/port。 

=== 软件包的管理

man:pkg_info[1] 是用于列出已安装的所有软件包列表和描述的程序。 

[source,shell]
....
# pkg_info
cvsup-16.1          A general network file distribution system optimized for CV
docbook-1.2         Meta-port for the different versions of the DocBook DTD
...
....

man:pkg_version[1]是一个用来统计所有安装的软件包版本的工具。 它可以用来比较本地 package 的版本与 ports 目录中的当前版本是否一致。 

[source,shell]
....
# pkg_version
cvsup                       =
docbook                     =
...
....

在第二列的符号指出了安装版本的相关时间和本地ports目录树中可用的版本。

[.informaltable]
[cols="1,1", frame="none", options="header"]
|===
| 符号
| 含义

|=
|在本地ports树中与已安装的软件包版本相匹配。

|<
|已安装的版本要比在ports树中的版本旧。

|>
|已安装的版本要比在ports树中的版本新 (本地的port树可能没有更新)。

|?
| 已安装的软件包无法在ports索引中找到。 (可能发生这种事情，举个例子， 您早先安装的一个 port 从 port 树中移出或改名了)

|*
|软件包有很多版本。

|!
|已安装的软件包在索引中存有记录， 但是由于某些原因 `pkg_version` 无法比较已安装的软件包与索引中相对应的版本号。
|===

=== 删除一个软件包

要删除先前安装的软件package，只要使用man:pkg_delete[1] 工具。 

[source,shell]
....
# pkg_delete xchat-1.7.1
....

需要注意的是， man:pkg_delete[1] 需要提供完整的包名； 如果您只是指定了类似 _xchat_ 而不是 _xchat-1.7.1_ 这样的名字， 则它将拒绝执行操作。 不过， 您可以使用 man:pkg_version[1] 来了解安装的 package 的版本。 除此之外， 也可以使用通配符：

[source,shell]
....
# pkg_delete xchat\*
....

这时， 所有名字以 `xchat` 开头的 package 都会被删掉。

=== 其它

所有已安装的 package 信息都保存在 [.filename]#/var/db/pkg# 目录下。 安装文件的列表和每个 package 的内容和描述都能在这个目录的相关文件中找到。 

[[ports-using]]
== 使用Ports Collection

下面的几个小节中， 给出了关于如何使用 Ports 套件来在您的系统中安装或卸载程序的介绍。 关于可用的 `make` targets 以及环境变量的介绍， 可以在 man:ports[7] 中找到。

[[ports-tree]]
=== 获得Ports Collection

在您能使用 ports 之前， 您必须先获得 Ports Collection - 本质上是 [.filename]#/usr/ports# 目录下的一堆 [.filename]#Makefile#、 补丁和描述文件。 

在您安装 FreeBSD 系统的时候， sysinstall 会询问您是否需要安装 Ports Collection。 如果您选择 no， 那您可以用下面的指令来安装 Ports Collection：

[.procedure]
====
*Procedure: CVSup 方法*

保持您本地 Ports 套件最新的一种快捷的方法， 是使用 CVSup 协议来进行更新。 如果您希望了解更多关于 CVSup 的细节， 请参见 crossref:mirrors[cvsup,使用 CVSup]。

[NOTE]
======
在 FreeBSD 系统里对 CVSup 的实现叫作 csup。
======

在首次运行 csup 之前， 务必确认 [.filename]#/usr/ports# 是空的！ 如果您之前已经用其他地方安装了一份 Ports 套件， 则 csup 可能不会自动删除已经在上游服务器上删除掉的补丁文件。

. 运行 `csup`:
+
[source,shell]
....
# csup -L 2 -h cvsup.FreeBSD.org /usr/shared/examples/cvsup/ports-supfile
....
+ 
将 _cvsup.FreeBSD.org_ 改为离您较近的 CVSup 服务器。 请参见 crossref:mirrors[cvsup-mirrors,CVSup 镜像] (crossref:mirrors[cvsup-mirrors,CVSup 站点]) 中的镜像站点完整列表。
+
[NOTE]
======
有时可能希望使用自己的 [.filename]#ports-supfile#， 比如说， 不想每次都通过命令行来指定所使用的 CVSup 服务器。

[.procedure]
****
.. 这种情况下， 需要以 `root` 身份将 [.filename]#/usr/shared/examples/cvsup/ports-supfile# 复制到新的位置， 例如 [.filename]#/root# 或您的主目录。
.. 编辑 [.filename]#ports-supfile#。
.. 把 _CHANGE_THIS.FreeBSD.org_ 修改成离您较近的 CVSup 服务器。 可以参考 crossref:mirrors[cvsup-mirrors,CVSup 镜像] (crossref:mirrors[cvsup-mirrors,CVSup 站点]) 中的镜像站点完整列表。
.. 接下来按如下的方式运行 `csup`：
+
[source,shell]
....
# csup -L 2 /root/ports-supfile
....
****
======
+
. 此后运行 man:csup[1] 命令将下载最近所进行的改动， 并将它们应用到您的 Ports Collection 上， 不过这一过程并不重新联编您系统上的 ports。
====

[.procedure]
====
*Procedure: Portsnap 方式*

Portsnap 是用于发布 Ports 套件的另一套系统。 请参阅 crossref:cutting-edge[updating-upgrading-portsnap,使用 Portsnap] 以了解关于 Portsnap 功能更详细的介绍。

. 下载压缩的 Ports 套件快照到 [.filename]#/var/db/portsnap#。 您可以根据需要在这之后关闭 Internet 连接。
+
[source,shell]
....
# portsnap fetch
....
+
. 假如您是首次运行 Portsnap， 则需要将快照释放到 [.filename]#/usr/ports#： 
+
[source,shell]
....
# portsnap extract
....
+ 
如果您已经有装好的 [.filename]#/usr/ports# 而您只想更新， 则应执行下面的命令：
+
[source,shell]
....
# portsnap update
....
====

[.procedure]
====
*Procedure: Sysinstall 方式*

这种方法需要使用 sysinstall 从安装介质上安装 Ports 套件。 注意， 安装的将是发布发行版时的旧版 Ports 套件。 如果您能访问 Internet， 应使用前面介绍的方法之一。

. 以 `root` 身份运行 `sysinstall`：
+
[source,shell]
....
# sysinstall
....
+
. 用光标向下选择 [.guimenuitem]#Configure#， 并按 kbd:[Enter]。
. 向下并选择 [.guimenuitem]#Distributions#， 按 kbd:[Enter]。
. 选择 [.guimenuitem]#ports#， 并按 kbd:[Space]。
. 选择 [.guimenuitem]#Exit#， 并按 kbd:[Enter]。
. 选择所希望的安装介质， 例如 CDROM、 FTP， 等等。
. 选择 [.guimenuitem]#Exit# 并按 kbd:[Enter]。
. 按 kbd:[X] 退出 sysinstall。
====

[[ports-skeleton]]
=== 安装 Ports

当提到 Ports Collection 时， 第一个要说明的就是何谓 "skeleton"。 简单地说， port skeleton 是让一个程序在 FreeBSD 上简洁地编译并安装的所需文件的最小组合。 每个 port skeleton 包含：

* 一个 [.filename]#Makefile#。 [.filename]#Makefile# 包括好几个部分， 指出应用程序是如何编译以及将被安装在系统的哪些地方。 
* 一个 [.filename]#distinfo# 文件。这个文件包括这些信息： 这些文件用来对下载后的文件校验和进行检查 (使用 man:sha256[1])， 来确保在下载过程中文件没有被破坏。 
* 一个 [.filename]#files# 目录。 这个目录包括在 FreeBSD 系统上编译和安装程序需要用到的补丁。 这些补丁基本上都是些小文件， 指出特定文件作了哪些修正。 它们都是纯文本的的格式，基本上是这样的 "删除第 10 行" 或 "将第 26 行改为这样 ..."， 补丁文件也被称作 "diffs"， 他们由 man:diff[1] 程序生成。 
+ 
这个目录也包含了在编译 port 时要用到的其它文件。
* 一个 [.filename]#pkg-descr# 文件。 这是一个提供更多细节，有软件的多行描述。
* 一个 [.filename]#pkg-plist# 文件。 这是即将被安装的所有文件的列表。它告诉 ports 系统在卸载时需要删除哪些文件。

一些ports还有些其它的文件， 例如 [.filename]#pkg-message#。 ports 系统在一些特殊情况下会用到这些文件。 如果您想知道这些文件更多的细节以及 ports 的概要， 请参阅 extref:{porters-handbook}[FreeBSD Porter's Handbook]。

port里面包含着如何编译源代码的指令， 但不包含真正的源代码。 您可以在网上或 CD-ROM 上获得源代码。 源代码可能被开发者发布成任何格式。 一般来说应该是一个被 tar 和 gzip 过的文件， 或者是被一些其他的工具压缩或未压缩的文件。 ports中这个程序源代码标示文件叫 "distfile"， 安装 FreeBSD port的方法还不止这两种。

[NOTE]
====
您必须使用 `root` 用户登录后安装 ports。
====

[WARNING]
====

在安装任何 port 之前， 应该首先确保已经更新到了最新的 Ports Collection， 并检查 http://vuxml.freebsd.org/[http://vuxml.freebsd.org/] 中是否有与那个 port 有关的安全问题。

在安装应用程序之前， 可以使用 portaudit 来自动地检查是否存在已知的安全问题。 这个工具同样可以在 Ports Collection (package:ports-mgmt/portaudit[]) 中找到。 在安装新的 port 之前， 可以考虑先运行一下 `portaudit -F` 来抓取最新的漏洞数据库。 在每天的周期性系统安全检察时， 数据库会被自动更新， 并且会在这之后实施安全审计。 欲了解进一步的情况，请参阅 man:portaudit[1] 和 man:periodic[8]。
====

Ports 套件假定您有可用的 Internet 连接。 如果您没有， 则需要将 distfile 手工放到 [.filename]#/usr/ports/distfiles# 中。

要开始操作， 首先进入要安装 port 的目录：

[source,shell]
....
# cd /usr/ports/sysutils/lsof
....

一旦进入了 [.filename]#lsof# 的目录，您将会看到这个port的结构。 下一步就是 make，或说 "联编" 这个 port。 只需在命令行简单地输入 `make` 命令就可轻松完成这一工作。 做好之后，您可以看到下面的信息：

[source,shell]
....
# make
>> lsof_4.57D.freebsd.tar.gz doesn't seem to exist in /usr/ports/distfiles/.
>> Attempting to fetch from ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/.
===>  Extracting for lsof-4.57
...
[extraction output snipped]
...
>> Checksum OK for lsof_4.57D.freebsd.tar.gz.
===>  Patching for lsof-4.57
===>  Applying FreeBSD patches for lsof-4.57
===>  Configuring for lsof-4.57
...
[configure output snipped]
...
===>  Building for lsof-4.57
...
[compilation output snipped]
...
#
....

注意，一旦编译完成，您就会回到命令行。 下一步安装 port， 要安装它只需要在 `make` 命令后跟上一个单词 `install` 即可：

[source,shell]
....
# make install
===>  Installing for lsof-4.57
...
[installation output snipped]
...
===>   Generating temporary packing list
===>   Compressing manual pages for lsof-4.57
===>   Registering installation for lsof-4.57
===>  SECURITY NOTE:
      This port has installed the following binaries which execute with
      increased privileges.
#
....

一旦您返回到提示符，您就可以运行您刚刚安装的程序了。因为 `lsof` 是一个赋予特殊权限的程序， 因此显示了一个安全警告。 在编译和安装 ports 的时候， 您应该留意任何出现的警告。

删除工作目录是个好主意， 这个目录中包含了全部在编译过程中用到的临时文件。 这些文件不仅会占用宝贵的磁盘空间， 而且可能会给升级新版本的 port 时带来麻烦。

[source,shell]
....
# make clean
===>  Cleaning for lsof-4.57
#
....

[NOTE]
====
使用 `make install clean` 可以一步完成 `make`、 `make install` 和 `make clean` 这三个分开的步骤的工作。
====

[NOTE]
====
一些 shell 会缓存环境变量 `PATH` 中指定的目录里的可执行文件， 以加速查找它们的速度。 如果您使用的是这类 shell， 在安装 port 之后可能需要执行 `rehash` 命令， 然后才能运行新安装的那些命令。 这个命令可以在类似 `tcsh` 的 shell 中使用。 对于类似 `sh` 的 shell， 对应的命令是 `hash -r`。 请参见您的 shell 的文档以了解进一步的情况。
====

某些第三方 DVD-ROM 产品， 如 http://www.freebsdmall.com/[FreeBSD Mall] 的 FreeBSD Toolkit 中包含了 distfiles。 这些文件可以与 Ports 套件配合使用。 将 DVD-ROM 挂接到 [.filename]#/cdrom#。 如果您使用不同的挂接点， 则应设置 make 变量 `CD_MOUNTPTS`。 如果盘上有需要的 distfiles， 则会自动使用。

[NOTE]
====
请注意， 少数 ports 并不允许通过 CD-ROM 发行。 这可能是由于下载之前需要填写注册表格， 或者不允许再次发布， 或者有一些其它原因。 如果您希望安装在 CD-ROM 上没有的 port， 就需要在线操作了。
====

ports 系统使用 man:fetch[1] 去下载文件， 它有很多可以设置的环境变量， 其中包括 `FTP_PASSIVE_MODE`、 `FTP_PROXY`， 和 `FTP_PASSWORD`。 如果您在防火墙之后，或使用 FTP/HTTP代理， 您就可能需要设置它们。 完整的说明请看 man:fetch[3]。

当使用者不是所有时间都能连接上网络， 则可以利用 `make fetch`。 您只要在顶层目录 ([.filename]#/usr/ports#) 下运行这个命令， 所有需要的文件都将被下载。 这个命令也同样可以在下级类别目录中使用， 例如： [.filename]#/usr/ports/net#。 注意， 如果一个port有一些依赖的库或其他 port， 它将 _不_ 下载这些依赖的 port 的 distfile 文件， 如果您想获取所有依赖的 port 的所有 distfile， 请用 `fetch-recursive` 命令代替 ``fetch``命令。

[NOTE]
====
您可以在一个类别或在顶级目录编译所有的 port， 或者使用上述提到的 ``make fetch``命令。 这样是非常危险的， 因为有一些port不能并存。 或者有另一种可能， 一些port会安装两个不同的文件， 但是却是相同的文件名。
====

在一些罕见的例子中， 用户可能需要在除了 `MASTER_SITES` 以外的一个站点(本地已经下载下来的文件)去获得一个文件包。 您可以用以下命令不使用 `MASTER_SITES`: 

[source,shell]
....
# cd /usr/ports/directory
# make MASTER_SITE_OVERRIDE= \
ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/distfiles/ fetch
....

在这个例子中，我们把 ``MASTER_SITES``这个选项改为了 ``ftp.FreeBSD.org/pub/FreeBSD/ports/distfiles/``。

[NOTE]
====
一些 port 允许 (或甚至要求) 您指定编译选项来 启用/禁用 应用程序中非必需的功能， 一些安全选项， 以及其他可以订制的内容。 具有代表性的包括 package:www/mozilla[]、 package:security/gpgme[]、 以及 package:mail/sylpheed-claws[]。 如果存在这样的选项， 通常会在编译时给出提示。
====

==== 改变默认的 Ports 目录

有时， 使用不同的工作临时目录和目标目录可能很有用 (甚至是必要的)。 可以用 `WRKDIRPREFIX` 和 `PREFIX` 这两个变量来改变默认的目录。 例如：

[source,shell]
....
# make WRKDIRPREFIX=/usr/home/example/ports install
....

将在 [.filename]#/usr/home/example/ports# 中编译 port 并把所有的文件安装到 [.filename]#/usr/local#。

[source,shell]
....
# make PREFIX=/usr/home/example/local install
....

将在 [.filename]#/usr/ports# 编译它并安装到 [.filename]#/usr/home/example/local#。

当然，

[source,shell]
....
# make WRKDIRPREFIX=../ports PREFIX=../local install
....

将包含两种设置 (没有办法在这一页把它写完， 但您应该已经知道怎么回事了)。

另外， 这些变量也可以作为环境变量来设置。 请参考您的 shell 的联机手册上关于如何设置环境变量的说明。

==== 处理 `imake`

一些 port 使用 `imake` (这是 X Window 系统的一部分) 不能正常地配合 `PREFIX`， 它们会坚持把文件安装到 [.filename]#/usr/X11R6# 下面。 类似地， 一些 Perl port 会忽略 `PREFIX` 并把文件安装到 Perl 的目录中。 让这些 port 尊重 `PREFIX` 是困难甚至是不可能的事情。

==== 重新配置 Ports

当你在编译某些 ports 的时候，可能会弹出一个基于 ncurses 的菜单来让你来选择一些编译选项。 通常用户都希望能够在一个 port 被编译安装了以后还能再次访问这份菜单以添加删除或修改这些选项。 实际上有很多方法来做这件事情。 一个方法进入那个 port 的目录后键入 `make config`， 之后便会再次显示出菜单和已选择的项目。 另一个方法是用 `make showconfig`， 这会给你显示出所有的配置选项。还有一个方法是执行 `make rmconfig`， 这将删除所有已选择的项目。 有关这些选项更详细的内容请参阅 man:ports[7]。

[[ports-removing]]
=== 卸载已经安装的 Ports

现在您已经了解了如何安装 ports， 并希望进一步了解如何卸载， 特别是在错误地安装了某个 port 之后。我们将卸载前面例子 (假如您没有注意的话， 是 `lsof`) 中安装的 port。 Ports 可以同 packages 以完全相同的方式 (在 <<packages-using,Packages 一节>> 中进行了介绍) 卸载， 方法是使用 man:pkg_delete[1] 命令：

[source,shell]
....
# pkg_delete lsof-4.57
....

[[ports-upgrading]]
=== 升级 Ports

首先， 使用 man:pkg_version[1] 命令来列出 Ports Collection 中提供了更新版本的那些 port：

[source,shell]
....
# pkg_version -v
....

[[ports-file-updating]]
==== [.filename]#/usr/ports/UPDATING#

在您更新了 Ports 套件之后， 在升级 port 之前， 应查看 [.filename]#/usr/ports/UPDATING#。 这个文件中介绍了在升级时用户应注意的问题， 以及一些可能需要进行的操作。 这可能包括更改文件格式、 配置文件位置的变动， 以及与先前版本的兼容性等等。

如果 [.filename]#UPDATING# 与本书中介绍的内容不同， 请以 [.filename]#UPDATING# 为准。

[[portupgrade]]
==== 使用 Portupgrade 来更新 Ports

portupgrade 工具是设计来简化升级已安装的 port 的操作的。 它通过 package:ports-mgmt/portupgrade[] port 来提供。 您可以像其它 port 那样， 使用 `make install clean` 命令来安装它：

[source,shell]
....
# cd /usr/ports/ports-mgmt/portupgrade
# make install clean
....

使用 `pkgdb -F` 命令来扫描已安装的 port 的列表， 并修正其所报告的不一致。 在每次升级之前， 有规律地执行它是个好主意。

运行 `portupgrade -a` 时， portupgrade 将开始并升级系统中所安装的所有过时的 ports。 如果您希望在每个升级操作时得到确认， 应指定 `-i` 参数。

[source,shell]
....
# portupgrade -ai
....

如果您只希望升级某个特定的应用程序， 而非全部可用的 port， 应使用 `portupgrade pkgname`。 如果 portupgrade 应首先升级指定应用程序的话， 则应指定 `-R` 参数。

[source,shell]
....
# portupgrade -R firefox
....

要使用预编译的 package 而不是 ports 来进行安装， 需要指定 `-P`。 如果指定了这个选项， portupgrade 会搜索 `PKG_PATH` 中指定的本地目录， 如果没有找到， 则从远程站点下载。 如果本地没有找到， 而且远程站点也没有成功地下载预编译包， 则 portupgrade 将使用 ports。 要禁止使用 port， 可以指定 `-PP`。

[source,shell]
....
# portupgrade -PP gnome2
....

如果只想下载 distfiles (或者， 如果指定了 `-P` 的话， 是 packages) 而不想构建或安装任何东西， 可以使用 `-F`。 要了解更多细节， 请参考 man:portupgrade[1]。

[[portmanager]]
==== 使用 Portmanager 来升级 Ports

Portmanager 是另一个用以简化已安装 port 升级操作的工具。 它可以通过 package:ports-mgmt/portmanager[] port 安装：

[source,shell]
....
# cd /usr/ports/ports-mgmt/portmanager
# make install clean
....

可以通过这个简单的命令来升级所有已安装的 port：

[source,shell]
....
# portmanager -u
....

如果希望 Portmanager 在进行每步操作之前都给出提示， 应使用 `-ui` 参数。 Portmanager 也可以用来在系统中安装新的 ports。 与通常的 `make install clean` 命令不同，它会在联编和安装您所选择的 port 之前升级所有依赖包。

[source,shell]
....
# portmanager x11/gnome2
....

如果关于所选 port 的依赖有任何问题， 可以用 Portmanager 来以正确的顺序重新构建它们。 完成之后， 有问题的 port 也将被重新构建。

[source,shell]
....
# portmanager graphics/gimp -f
....

要了解更多信息， 请参见 man:portmanager[1]。

[[portmaster]]
==== 使用 Portmaster 升级 Ports

Portmaster 是另外一个用来升级已安装的 ports 的工具。 Portmaster 被设计成尽可能使用 "基本" 系统中能找到的工具 （它不依赖于其他的 ports） 和 [.filename]#/var/db/pkg/# 中的信息来检测出需要升级的 ports。你可以在 package:ports-mgmt/portmaster[] 找到它：

[source,shell]
....
# cd /usr/ports/ports-mgmt/portmaster
# make install clean
....

Portmaster groups ports into four categories:

Portmaster 把 ports 分成4类：

* Root ports (不依赖其他的 ports，也不被依赖)
* Trunk ports (不依赖其他的 ports，但是被其他的 ports 依赖)
* Branch ports (依赖于其他的 ports，同时也被依赖)
* Leaf ports (依赖于其他的 ports，但不被依赖)

你可以使用 `-L` 选项列出所有已安装的 ports 和查找存在更新的 ports：

[source,shell]
....
# portmaster -L
===>>> Root ports (No dependencies, not depended on)
===>>> ispell-3.2.06_18
===>>> screen-4.0.3
        ===>>> New version available: screen-4.0.3_1
===>>> tcpflow-0.21_1
===>>> 7 root ports
...
===>>> Branch ports (Have dependencies, are depended on)
===>>> apache-2.2.3
        ===>>> New version available: apache-2.2.8
...
===>>> Leaf ports (Have dependencies, not depended on)
===>>> automake-1.9.6_2
===>>> bash-3.1.17
        ===>>> New version available: bash-3.2.33
...
===>>> 32 leaf ports

===>>> 137 total installed ports
        ===>>> 83 have new versions available

....

可以使用这个简单的命令升级所有已安装的 ports：

[source,shell]
....
# portmaster -a
....

[NOTE]
====
Portmaster 默认在删除一个现有的 port 前会做一个备份包。如果新的版本能够被成功安装， Portmaster 将删除备份。 使用 `-b` 后 Portmaster 便不会自动删除备份。加上 `-i` 选项之后 Portmaster 将进入互动模式， 在升级每个 port 以前提示你给予确认。
====

如果你在升级的过程中发现了错误，你可以使用 `-f` 选项升级/重新编译所有的 ports：

[source,shell]
....
# portmaster -af
....

同样你也可以使用 Portmaster 往系统里安装新的 ports，升级所有的依赖关系之后并安装新的 port：

[source,shell]
....
# portmaster shells/bash
....

更多的详细信息请参阅 man:portmaster[8]

[[ports-disk-space]]
=== Ports 和磁盘空间

使用 Ports 套件会最终用完磁盘空间。 在通过 ports 联编和安装软件之后，您应记得清理临时的 [.filename]#work# 目录， 其方法是使用 `make clean` 命令。 您可以使用下面的命令来清理整个 Ports 套件：

[source,shell]
....
# portsclean -C
....

随着时间的推移， 您可能会在 [.filename]#distfiles# 目录中积累下大量源代码文件。 您可以手工删除这些文件， 也可以使用下面的命令来删除所有 port 都不引用的文件：

[source,shell]
....
# portsclean -D
....

除此之外， 也可以用下列命令删去目前安装的 port 没有使用的源码包文件：

[source,shell]
....
# portsclean -DD
....

[NOTE]
====
这个 `portsclean` 工具是 portupgrade 套件的一部分。
====

不要忘记删除那些已经安装， 但已不再使用的 ports。 用于自动完成这种工作的一个好工具是 package:ports-mgmt/pkg_cutleaves[] port。

[[ports-nextsteps]]
== 安装之后还要做点什么？

通常，您通过port安装完一个软件后,可以阅读它带的一些文档(如果它包含文档的话)， 或需要编辑它的配置文件，来确保这个软件的运行， 或在机器启动的时候启动(如果它是一个服务的话)，等等。

对于不同的软件有着不同的配置步骤。不管怎样， 如果您装好了一个软件，但是不知道下一步怎么办的时候， 这些小技巧可能可以帮助您:

* 使用 man:pkg_info[1] 命令，它能找到安装了哪些文件，以及装在哪里。 举个例子，如果您安装了 FooPackage version 1.0.0, 那么这个命令
+
[source,shell]
....
# pkg_info -L foopackage-1.0.0 | less
....
+ 
将显示这个软件包安装的所有文件，您要特别注意在[.filename]##man/##目录里面的文件， 它们可能是手册，[.filename]##etc/##目录里面的配置文件，以及 [.filename]##doc/##目录下面更多的文档。
+ 
如果您不确定已经安装好的软件版本，您可以使用这样的命令
+
[source,shell]
....
# pkg_info | grep -i foopackage
....
+ 
它将会找到所有已安装的软件包名字中包含__foopackage__ 的软件包。 对于其他的查找， 您只需要在命令行中替换 _foopackage_。
* 一旦一些软件手册已被您确认安装，您可以使用 man:man[1] 查看它。 同样的，如果有的话，您还可以完整的查看一遍配置文件的示例，以及任何额外的文档。
* 如果应用软件有网站, 您还可以从网站上找到文档，常见问题的解答，或其他更多。 如果您不知道它们的网站地址，请使用下面的命令
+
[source,shell]
....
# pkg_info foopackage-1.0.0
....
+ 
一个 `WWW:` 行, 如果它存在， 它将提供一个这个应用程序的网站URL.
* Ports 如果需要在服务器启动时运行(就像互联网服务器)， 它通常会把一个脚本的样例放入 [.filename]#/usr/local/etc/rc.d# 目录。为了保证正确性， 您可以查看这个脚本， 并编辑或更改这个脚本的名字。 详情请看crossref:config[configtuning-starting-services,启动服务]。

[[ports-broken]]
== 如何处理坏掉的 Ports

如果您发现某个 port 无法正常工作， 有几件事值得尝试， 包括：

. 在 link:https://www.FreeBSD.org/support/#gnats[问题报告数据库] 中查找是否有尚未提交的修正。 如果有， 可以使用所提议的修正。
. 要求 port 的监护人 (maintainer) 提供帮助。 输入 `make maintainer` 或阅读 [.filename]#Makefile# 查找监护人的电子邮件地址。 请记得把 port 的名字和版本写在邮件里 ([.filename]#Makefile# 中的 ``$FreeBSD:``这一行) 并把错误输出的头几行发给 maintainer。
+
[NOTE]
====
某些 ports 并非一个人维护， 而是写了一个 extref:{mailing-list-faq}[邮件列表]。 许多， 但并非所有 port， 使用类似 mailto:freebsd-listname@FreeBSD.org[freebsd-listname@FreeBSD.org] 这样的地址。 请在提出问题时考虑这一点。

特别地， 由 mailto:ports@FreeBSD.org[ports@FreeBSD.org] 监护的 port， 实际上并没有人维护。 订阅这个邮件列表的人们会感谢您提供的修正和支持。 我们一直都需要更多志愿者！
====
+ 
如果您没有得到回应， 则可以使用 man:send-pr[1] 来提交问题报告 (请参见 extref:{problem-reports}[如何撰写 FreeBSD 问题报告])。
. 修正它！ extref:{porters-handbook}[Porter 手册] 中提供了关于 "Ports" 基础设施的详细信息， 通过了解这些内容， 您就能修正偶然坏掉的 port， 或甚至提交自己的 port 了！
. 从较近的 FTP 站点下载一个编译好的安装包。 "中央的" package collection 在 `ftp.FreeBSD.org` 的 link:ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/packages/[packages 目录中]， 但 _在此之前_ 请 _事先_ 检查一下是否存在较近的 crossref:mirrors[mirrors-ftp,镜像网站]！ 通常情况下这些安装包都可以直接使用， 而且应该比自行编译快一些。 安装过程本身可以通过 man:pkg_add[1] 来完成。
