> For the complete documentation index, see [llms.txt](https://book.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://book.bsdcn.org/man/man8/adduser.8.md).

# adduser.8

`adduser` — 添加新用户的命令

## 名称

`adduser`

## 概要

`adduser [-CDENSZhq] [-G groups] [-L login_class] [-M mode] [-d partition] [-f file] [-g login_group] [-k dotdir] [-m message_file] [-s shell] [-u uid_start] [-w type]`

## 描述

`adduser` 是一个 shell 脚本，基于 [pw(8)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man8/pw.8.md) 命令实现，用于添加新用户。它会创建 passwd/group 条目、主目录，复制点文件，并向新用户发送欢迎消息。在主目录父目录为 ZFS 数据集的系统上，除非系统管理员另有指定，`adduser` 默认会将主目录创建为 ZFS 数据集。它支持两种操作模式：既可以在命令行交互式地一次添加一个用户，也可以从文件中读取新用户列表，在无需用户交互的情况下以批处理模式运行。

## 限制

**username** 登录名。用户名受限于 [pw(8)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man8/pw.8.md) 接受的范围。通常这意味着它只能包含小写字母或数字，但不能以 `-` 字符开头。最大长度为 16 个字符。这一限制有其历史原因。尽管人们出于美观原因一直希望突破此限制，但打破 UNIX 中如此基础的根本参数从来都不是很重要。你可以在 `<utmp.h>` 中修改 `UT_NAMESIZE` 并重新编译整个系统；有人这样做过且可行，但任何预编译程序或假定 8 字符名称限制的源代码（如 NIS）都会出问题。NIS 协议规定用户名为 8 个字符。如果你需要更长的登录名用于电子邮件地址，可以在 **/etc/mail/aliases** 中定义别名。

**full name** 这通常称为 gecos 字段，一般包含用户的全名。此外，它还可以包含以逗号分隔的值列表，如办公室号码、工作电话和家庭电话。如果名称中包含 & 符号，在其他程序显示时会被替换为首字母大写的登录名。不允许使用 `:` 字符。

**shell** 除非提供 `-S` 参数，否则只允许使用 shell 数据库（**/etc/shells**）中的有效 shell。此外，可以提供 shell 的基本名称或完整路径。

**UID** 自动生成或由你选择。必须小于 32000。

**GID/login group** 自动生成或由你选择。必须小于 32000。

**password** 你可以选择空密码、禁用密码、使用随机生成的密码，或指定自己的明文密码（在存入用户数据库前会被加密）。

## 唯一组

或许你忽略了这种方案能实现而大多数其他方案做不到的事情。让每个用户处于各自的组中，他们可以安全地以 002 的 umask 运行，而不是通常的 022，并在主目录中创建文件，而无需担心其他人能够修改它们。

对于共享区域，你创建一个单独的 UID/GID，将每个应能访问该区域的人放入该新组。

这种 UID/GID 管理模型比把用户塞进组里、在共享区域工作时还要折腾 umask 灵活得多。

我使用此模型已近 10 年，发现它适用于大多数情况，且从未造成妨碍。（Rod Grimes）

## 配置

`adduser` 从 **/etc/adduser.conf** 读取配置信息。如果此文件不存在，将使用预定义的默认值。虽然可以手动编辑此文件，但更安全的选择是使用 `-C` 命令行参数。使用此参数时，`adduser` 会启动交互式输入，将提示的答案保存到 **/etc/adduser.conf**，然后立即退出而不修改用户数据库。命令行上指定的选项优先于此文件中保存的任何值。

## 选项

**`-C`** 创建新的配置文件并退出。此选项与 `-f` 选项互斥。

**`-d`** `partition` 主目录分区。默认分区，所有用户目录将位于其下。**/nonexistent** 分区被视为特殊。`adduser` 脚本不会创建和填充该名称的主目录。否则，默认情况下它会尝试创建主目录。

**`-D`** 不尝试创建主目录。

**`-E`** 禁用账户。此选项会通过在密码字段前添加字符串 “`*LOCKED*`” 来锁定账户。超级用户可以使用 [pw(8)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man8/pw.8.md) 命令解锁账户：

```sh
pw unlock [name | uid]
```

**`-f`** `file` 从 `file` 获取要创建的账户列表。如果 `file` 为 “`-`”，则从标准输入获取列表。如果指定了此选项，`adduser` 将以批处理模式运行，不寻求任何用户输入。如果处理某个账户时遇到错误，它会向标准错误写入消息并继续处理下一个账户。输入文件的格式如下所述。

**`-g`** `login_group` 通常，如果未指定登录组，则假定其与用户名相同。此选项将 `login_group` 设为默认值。

**`-G`** `groups` 以空格分隔的附加组列表。此选项允许用户指定要将用户添加到的附加组。用户除了其登录组外，还是这些组的成员。

**`-h`** 打印选项摘要并退出。

**`-k`** `directory` 将 `directory` 中的文件复制到新用户的主目录；`dot.foo` 会被重命名为 `.foo`。

**`-L`** `login_class` 设置默认登录类。

**`-m`** `file` 从 `file` 向新用户发送欢迎消息。将 `file` 指定为 `no` 会导致不向新用户发送消息。请注意，消息文件可以引用 `adduser` 脚本的内部变量。

**`-M`** `mode` 以 `mode` 权限创建主目录，并受当前 umask(2) 修改。

**`-N`** 不读取默认配置文件。

**`-q`** 最少的用户反馈。特别是，随机密码不会回显到标准输出。

**`-s`** `shell` 新用户的默认 shell。`shell` 参数可以是 shell 的基本名称或完整路径。除非提供 `-S` 参数，否则 shell 必须存在于 **/etc/shells** 中，或为特殊 shell *nologin* 才被视为有效 shell。

**`-S`** 不检查指定 shell 的存在性或有效性。

**`-u`** `uid` 从 `uid` 开始使用 UID。

**`-w`** `type` 密码类型。`adduser` 允许用户指定要创建的密码类型。`type` 参数可取以下值之一：

**`no`** 禁用密码。密码字段将包含单个 `*` 字符，而非加密字符串。在超级用户手动启用密码之前，用户无法登录。

**`none`** 使用空字符串作为密码。

**`yes`** 使用用户提供的字符串作为密码。在交互模式下，会提示用户输入密码。在批处理模式下，假定该行最后一个（第 10 个）字段为密码。

**`random`** 生成随机字符串并将其作为密码。密码将回显到标准输出。此外，它还可以通过 `randompass` 变量包含在消息文件中。

**`-Z`** 不尝试创建 ZFS 主数据集。

## 格式

使用 `-f` 选项时，账户信息必须以特定格式存储。所有空行或以 `#` 开头的行都将被忽略。所有其他行必须包含十个以冒号（`:`）分隔的字段，如下所述。命令行选项不优先于字段中的值。只有密码字段可以包含 `:` 字符作为字符串的一部分。

```sh
name : uid : gid : class : change : expire : gecos : home_dir : shell : password
```

**`name`** 登录名。此字段不能为空。

**`uid`** 数字登录用户 ID。如果此字段留空，将自动生成。

**`gid`** 数字主组 ID。如果此字段留空，将创建一个与用户名同名的组，并使用其 GID 代替。

**`class`** 登录类。此字段可留空。

**`change`** 密码时效。此字段表示账户的密码更改日期。此字段的格式与 [pw(8)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man8/pw.8.md) 的 `-p` 参数格式相同。它可以是 `dd`-`mmm`-`yy`\[`yy`]，其中 `dd` 表示日，`mmm` 表示月份（数字或字母格式：“`10`” 或 “`Oct`”），`yy`\[`yy`] 是四位或两位年份。要表示相对于当前日期的时间，格式为：+`n`\[`mhdwoy`]，其中 `n` 表示一个数字，后跟分钟、小时、天、周、月或年，表示密码必须在此时间后更改。此字段可留空以关闭此功能。

**`expire`** 账户过期。此字段表示账户的过期日期。指定日期之后账户将无法使用。此字段的格式与密码时效相同。此字段可留空以关闭此功能。

**`gecos`** 用户的全名和其他附加信息。

**`home_dir`** 主目录。如果此字段留空，将通过在主目录分区后附加用户名自动创建。**/nonexistent** 主目录被视为特殊，表示不为用户创建主目录。

**`shell`** 登录 shell。此字段应包含有效登录 shell 的基本名称或完整路径。

**`password`** 用户密码。此字段应包含明文字符串，在存入用户数据库前会被加密。如果密码类型为 `yes` 且此字段为空，则假定账户具有空密码。如果密码类型为 `random` 且此字段*不*为空，其内容将用作密码。如果 `-w` 选项与 `no` 或 `none` 参数一起使用，此字段将被忽略。注意不要以 `:` 结束此字段，因为它会被视为密码的一部分。

## 文件

**/etc/master.passwd** 用户数据库 **/etc/group** 组数据库 **/etc/shells** shell 数据库 **/etc/login.conf** 登录类数据库 **/etc/adduser.conf** `adduser` 的配置文件 **/etc/adduser.message** `adduser` 的消息文件 **/usr/share/skel** 骨架登录目录 **/var/log/userlog** `adduser` 的日志文件

## 参见

chpass(1), [passwd(1)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man1/passwd.1.md), adduser.conf(5), aliases(5), [group(5)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man5/group.5.md), login.conf(5), [passwd(5)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man5/passwd.5.md), [shells(5)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man5/shells.5.md), [groups(7)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man7/groups.7.md), [pw(8)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man8/pw.8.md), pwd\_mkdb(8), [rmuser(8)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man8/rmuser.8.md), vipw(8), [yp(8)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man8/yp.8.md)

## 历史

`adduser` 命令首次出现在 FreeBSD 2.1 中。

## 作者

本手册页和最初的 Perl 脚本由 Wolfram Schneider <wosch@FreeBSD.org> 编写。替换脚本以 POSIX shell 脚本编写并做了一些增强，配套的手册页修改由 Mike Makonnen <mtm@identd.net> 完成。

## 缺陷

为了让 `adduser` 在发送给新用户的消息中正确扩展诸如 `$username` 和 `$randompass` 之类的变量，它必须让 shell 评估消息文件的每一行。这意味着消息文件中也可以嵌入 shell 命令。`adduser` 试图通过拒绝评估并非由 root 用户拥有且仅 root 可写的文件，来降低攻击者利用此功能的可能性。此外，在消息文件中使用 shell 特殊字符和运算符时必须进行转义。

另外，密码时效和账户过期时间目前只能在批处理模式下或通过 **/etc/adduser.conf** 设置。用户应也能在交互模式下设置它们。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://book.bsdcn.org/man/man8/adduser.8.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
