# 14.3.管理 FreeBSD 中的服务

FreeBSD 使用 [rc(8)](https://man.freebsd.org/cgi/man.cgi?query=rc\&sektion=8\&format=html) 启动脚本系统，在系统初始化期间以及管理服务时使用。

列出的 **/etc/rc.d** 脚本提供基本服务，可以使用 `start`、`stop` 和 `restart` 选项通过 [service(8)](https://man.freebsd.org/cgi/man.cgi?query=service\&sektion=8\&format=html) 控制。

一个基本的脚本可能类似于以下内容：

```sh
#!/bin/sh
#
# PROVIDE: utility
# REQUIRE: DAEMON
# KEYWORD: shutdown

. /etc/rc.subr

name=utility
rcvar=utility_enable

command="/usr/local/sbin/utility"

load_rc_config $name

#
# 不要在这里更改这些默认值
# 请在 /etc/rc.conf 文件中设置它们
#
utility_enable=${utility_enable-"NO"}
pidfile=${utility_pidfile-"/var/run/utility.pid"}

run_rc_command "$1"
```

有关如何创建自定义 [rc(8)](https://man.freebsd.org/cgi/man.cgi?query=rc\&sektion=8\&format=html) 脚本的说明，请参阅 [这篇文章](https://docs.freebsd.org/en/articles/rc-scripting/)。

## 14.3.1. 启动服务

许多用户通过 Ports 在 FreeBSD 上安装第三方软件，并需要在系统初始化时启动已安装的服务。

例如，服务如 [security/openssh-portable](https://cgit.freebsd.org/ports/tree/security/openssh-portable/) 或 [www/nginx](https://cgit.freebsd.org/ports/tree/www/nginx/) 是可能在系统初始化时启动的众多软件包中的两个。本节解释了启动服务的可用步骤。

由于 [rc(8)](https://man.freebsd.org/cgi/man.cgi?query=rc\&sektion=8\&format=html) 系统主要用于在系统启动和关闭时启动和停止服务，因此 `start`、`stop` 和 `restart` 选项只有在相应的 **/etc/rc.conf** 变量设置时才会执行其操作。

因此，启动服务的第一步，例如 [www/nginx](https://cgit.freebsd.org/ports/tree/www/nginx/)，是通过执行以下命令将其添加到 **/etc/rc.conf** 中：

```sh
# sysrc nginx_enable="YES"
```

然后，可以通过执行以下命令启动 nginx：

```sh
# service nginx start
```

> **技巧**
>
> 要 `start`、`stop` 或 `restart` 一个服务，而不管 **/etc/rc.conf** 中的设置如何，可以在命令前加上 "one"。例如，要在不管当前 **/etc/rc.conf** 设置的情况下启动 [www/nginx](https://cgit.freebsd.org/ports/tree/www/nginx/)，可以执行以下命令：
>
> ```sh
> # service nginx onestart
> ```

还可以将服务自动放入 jail 中，参见相关的 [Service Jails](https://docs.freebsd.org/en/books/handbook/jails/#service-jails) 解释。

## 14.3.2. 服务状态

要确定服务是否正在运行，请使用 `status` 子命令。

例如，要验证 [www/nginx](https://cgit.freebsd.org/ports/tree/www/nginx/) 是否正在运行：

```sh
# service nginx status
```

输出应类似于以下内容：

```sh
nginx is running as pid 27871.
```

## 14.3.3. 重新加载服务

在某些情况下，还可以 `reload` 一个服务。这会尝试向单个服务发送信号，强制服务重新加载其配置文件。

在大多数情况下，这意味着向服务发送 `SIGHUP` 信号。

**并非所有服务都支持此功能。**

[rc(8)](https://man.freebsd.org/cgi/man.cgi?query=rc\&sektion=8\&format=html) 系统用于网络服务，并且也参与了大部分系统初始化。例如，当执行 **/etc/rc.d/bgfsck** 脚本时，它会输出以下消息：

```sh
Starting background file system checks in 60 seconds.
```

此脚本用于后台文件系统检查，仅在系统初始化期间执行。

许多系统服务依赖于其他服务才能正常运行。例如，[yp(8)](https://man.freebsd.org/cgi/man.cgi?query=yp\&sektion=8\&format=html) 和其他基于 RPC 的服务，可能会在 [rpcbind(8)](https://man.freebsd.org/cgi/man.cgi?query=rpcbind\&sektion=8\&format=html) 服务启动后才会成功启动。

更多信息可以在 [rc(8)](https://man.freebsd.org/cgi/man.cgi?query=rc\&sektion=8\&format=html) 和 [rc.subr(8)](https://man.freebsd.org/cgi/man.cgi?query=rc.subr\&sektion=8\&format=html) 中找到。

## 14.3.4. 使用服务启动其他服务

其他服务可以通过 [inetd(8)](https://man.freebsd.org/cgi/man.cgi?query=inetd\&sektion=8\&format=html) 启动。有关 [inetd(8)](https://man.freebsd.org/cgi/man.cgi?query=inetd\&sektion=8\&format=html) 及其配置的详细说明，请参阅 [“The inetd Super-Server”](https://docs.freebsd.org/en/books/handbook/network-servers/#network-inetd)。

在某些情况下，使用 [cron(8)](https://man.freebsd.org/cgi/man.cgi?query=cron\&sektion=8\&format=html) 启动系统服务可能更有意义。这个方法有几个优点，因为 [cron(8)](https://man.freebsd.org/cgi/man.cgi?query=cron\&sektion=8\&format=html) 以 [crontab(5)](https://man.freebsd.org/cgi/man.cgi?query=crontab\&sektion=5\&format=html) 所有者的身份运行这些进程。这允许普通用户启动并维护自己的应用程序。

[cron(8)](https://man.freebsd.org/cgi/man.cgi?query=cron\&sektion=8\&format=html) 的 `@reboot` 特性可以代替时间指定。这会使作业在 [cron(8)](https://man.freebsd.org/cgi/man.cgi?query=cron\&sektion=8\&format=html) 启动时运行，通常是在系统初始化期间。
