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

# ar(1)

`ar` — 管理归档文件

## 名称

`ar`, `ranlib`

## 概要

`ranlib -d [-T] [-f] [-j] [-v] [-z] archive file ranlib -m [-T] [-a position-after] [-b position-before] [-f] [-i position-before] [-j] [-s -| -S] [-z] archive file ranlib -p [-T] [-f] [-v] archive [file] ranlib -q [-T] [-c] [-D] [-f] [-s -| -S] [-U] [-v] [-z] archive file ranlib -r [-T] [-a position-after] [-b position-before] [-c] [-D] [-f] [-i position-before] [-j] [-s -| -S] [-u] [-U] [-v] [-z] archive file ranlib -s [-j] [-z] archive ranlib -t [-f] [-T] [-v] archive [file] ranlib -x [-C] [-T] [-f] [-o] [-u] [-v] archive [file] ranlib -M ranlib [-D] [-U] archive ...`

## 描述

`ranlib` 实用程序创建和维护组合成归档的文件组。归档创建后，可以向其中添加新文件，也可以提取、删除或替换已有文件。

文件在归档中按其文件名的最后一个组成部分命名，因此如果通过包含“/”的路径引用的文件被归档，它将以路径的最后一个组成部分命名。同样，在将命令行上列出的路径与归档中存储的文件名进行匹配时，仅比较路径的最后一个组成部分。

`ranlib` 的常规用途是创建和维护适合与链接编辑器 [ld(1)](/man1/ld.lld.1.md) 配合使用的库，但不限于此目的。`ranlib` 实用程序可以创建和管理归档符号表（参见 [ar(5)](/man5/ar.5.md)），用于加速链接编辑操作。如果归档中存在符号表，后续对归档的操作会使其保持最新。

`ranlib` 实用程序用于向现有归档添加归档符号表。

## 选项

`ranlib` 实用程序支持以下选项：

**`-a`** `member-after` 与 `-m` 选项一起使用时，该选项指定将参数 `file` 指定的归档成员移动到参数 `member-after` 所指归档成员之后。与 `-r` 选项一起使用时，该选项指定将参数 `file` 指定的文件添加到参数 `member-after` 所指归档成员之后。

**`-b`** `member-before` 与 `-m` 选项一起使用时，该选项指定将参数 `file` 指定的归档成员移动到参数 `member-before` 所指归档成员之前。与 `-r` 选项一起使用时，该选项指定将参数 `file` 指定的文件添加到参数 `member-before` 所指归档成员之前。

**`-c`** 抑制使用 `-r` 和 `-q` 选项创建新归档时打印的提示信息。

**`-C`** 防止提取的文件覆盖文件系统中同名文件。

**`-d`** 从参数 `archive` 指定的归档中删除参数 `file` 指定的成员。归档的符号表（如果存在）会更新以反映归档的新内容。

**`-D`** 与 `-r` 或 `-q` 选项组合使用、单独使用 `-s` 选项，或以 `ranlib` 名字调用时，对于由参数指定的成员，插入 0 而非真实的 mtime、uid 和 gid 值，并使用 0644 替代文件模式。这确保了当成员内容相同时，所得归档的校验和可复现。该选项默认启用。如果在命令行上指定了多个 `-D` 和 `-U` 选项，以最后一个为准。

**`-f`** 命名归档成员时，仅使用归档成员名或命令行文件名参数的前十五个字符。

**`-i`** `member-before` 与 `-b` 选项同义。

**`-j`** 该选项被接受但被忽略。

**`-l`** 该选项为与 GNU [ar(1)](/man1/ar.1.md) 兼容而保留，但被忽略。

**`-m`** 在归档内移动由参数 `file` 指定的归档成员。如果已通过 `-a`、`-b` 或 `-i` 选项之一指定了位置，则成员被移动到指定位置之前或之后。如果未指定位置，指定的成员被移动到归档末尾。如果归档有符号表，会更新以反映归档的新内容。

**`-M`** 从标准输入读取并执行 MRI 库管理命令。`ranlib` 实用程序可识别的命令在“MRI 库管理命令”小节中描述。

**`-o`** 提取成员时保留其原始修改时间。

**`-p`** 将参数 `file` 指定的归档成员的内容写入标准输出。如果未指定成员，则按归档中出现的顺序写入归档中所有文件的内容。

**`-q`** 将参数 `file` 指定的文件追加到参数 `archive` 指定的归档中，不检查文件是否已存在于归档中。归档符号表会根据需要更新。如果参数 `archive` 指定的文件尚不存在，将创建新归档。

**`-r`** 在参数 `archive` 指定的归档中替换（添加）参数 `file` 指定的文件，必要时创建归档。替换已有成员不会改变归档内成员的顺序。如果参数 `file` 中指定的文件不存在，归档中与该名称匹配的已有成员不会被更改。除非指定了 `-a`、`-b` 或 `-i` 定位选项之一，否则新文件被添加到归档末尾。如果归档符号表存在，会更新以反映归档的新状态。

**`-s`** 向参数 `archive` 指定的归档添加归档符号表（参见 [ar(5)](/man5/ar.5.md)）。单独使用 `-s` 选项调用 `ranlib` 等效于调用 `ranlib`。

**`-S`** 不生成归档符号表。

**`-t`** 按文件在归档中出现的顺序列出参数 `file` 指定的文件，每行一个。如果未指定文件，则列出归档中的所有文件。

**`-T`** 该选项被接受但被忽略。在其他 `ranlib` 实现中，`-T` 创建“精简”归档。

**`-u`** 有条件地更新归档或提取成员。与 `-r` 选项一起使用时，如果参数 `file` 指定的文件比其归档版本新，则替换归档中的该文件。与 `-x` 选项一起使用时，仅当参数 `file` 指定的成员比文件系统中对应文件新时才提取。

**`-U`** 与 `-r` 或 `-q` 选项组合使用时，对于由参数指定的成员，插入真实的 mtime、uid、gid 和文件模式值。如果在命令行上指定了多个 `-D` 和 `-U` 选项，以最后一个为准。

**`-v`** 提供详细输出。与 `-d`、`-m`、`-q` 或 `-x` 选项一起使用时，`ranlib` 逐文件描述正在执行的归档修改，由三个以空白分隔的字段组成：选项字母、短划线“-”和文件名。与 `-r` 选项一起使用时，`ranlib` 按上述方式显示描述，但如果文件被添加到归档中，首字母为“a”；如果文件替换了归档中已有的文件，首字母为“r”。与 `-p` 选项一起使用时，以“<”和“>”字符括起来的文件名被写入标准输出，前加一个换行符，后跟两个换行符。指定文件的内容紧跟在文件名之后。与 `-t` 选项一起使用时，`ranlib` 显示八个以空白分隔的字段：由 strmode(3) 显示的文件权限、以斜杠（“/”）分隔的十进制用户 ID 和组 ID、以字节为单位的文件大小、以 strftime(3) 格式“%b %e %H:%M %Y”显示的文件修改时间，以及文件名。

**`-V`** 打印版本字符串并退出。

**`-x`** 将参数 `file` 指定的归档成员提取到当前目录。如果未指定成员，则提取归档的所有成员。如果与提取成员对应的文件不存在，则创建该文件。如果与提取成员对应的文件已存在，其所有者和组不会被更改，而其内容将被覆盖，权限将设置为归档中记录的值。除非指定了 `-o` 选项，否则文件的访问和修改时间为提取时间。

**`-z`** 该选项被接受但被忽略。

### MRI 库管理命令

如果指定了 `-M` 选项，`ranlib` 实用程序将从标准输入读取并执行命令。如果标准输入是终端，`ranlib` 实用程序会在读取每行前显示提示符“`AR >`”，即使遇到错误也会继续运行。如果标准输入不是终端，`ranlib` 实用程序不会显示提示符，并在遇到错误时终止执行。

每行输入包含一条命令。输入行中的单词以空白字符分隔。行的第一个单词是命令，其余单词是命令的参数。命令单词不区分大小写。参数可以用逗号或空格分隔。

允许空行，空行会被忽略。长行可以通过以“`+`”字符结尾来续行。

“`*`”和“`;`”字符开始注释。注释延伸至行尾。

执行 MRI 库管理脚本时，`ranlib` 实用程序在归档的临时副本上操作。使用 `save` 命令将对副本的更改永久化。

`ranlib` 实用程序可识别的命令如下：

**`addlib`** `archive |` `addlib` `archive` (`member` \[, `member` ]...]) 将参数 `archive` 指定的归档内容添加到当前归档。如果使用参数 `member` 指定了特定成员，则仅将那些成员添加到当前归档。如果未指定成员，则将整个归档内容添加到当前归档。

**`addmod`** `member` \[, `member` ]...] 将参数 `member` 指定的文件添加到当前归档。

**`clear`** 丢弃当前归档的所有内容。

**`create`** `archive` 创建由参数 `archive` 命名的新归档，并将其设为当前归档。如果指定的归档已存在，在发出 `save` 命令时将被覆盖。

**`delete`** `module` \[, `member` ]...] 从当前归档中删除由参数 `member` 指定的模块。

**`directory`** `archive` (`member` \[, `member` ]... )\[`outputfile`]] 列出归档中每个指定的模块。输出格式取决于使用 `verbose` 命令设置的详细程度。输出发送到标准输出或参数 `outputfile` 指定的文件。

**`end`** 成功退出 `ranlib` 实用程序。当前归档的任何未保存更改将被丢弃。

**`extract`** `member` \[, `member` ]...] 从当前归档中提取由参数 `member` 指定的成员。

**`list`** 以详细方式显示当前归档的内容。

**`open`** `archive` 打开由参数 `archive` 指定的归档，并将其设为当前归档。

**`replace`** `member` \[, `member` ]...] 用参数 `member` 指定的文件替换当前归档中的指定成员。文件必须存在于当前目录中，且指定的模块必须已存在于当前归档中。

**`save`** 将所有更改提交到当前归档。

**`verbose`** 切换 `directory` 命令的详细程度。

## 实例

创建包含三个文件 `ex1.o`、`ex2.o` 和 `ex3.o` 的新归档 `ex.a`，使用：

```sh
ar -rc ex.a ex1.o ex2.o ex3.o
```

向现有归档 `ex.a` 添加归档符号表，使用：

```sh
ar -s ex.a
```

从归档 `ex.a` 中删除文件 `ex1.o`，使用：

> ar -d ex.a ex1.o

详细列出归档 `ex.a` 的内容，使用：

> ar -tv ex.a

使用 MRI 库管理命令创建包含文件 `ex1.o` 和 `ex2.o` 的新归档 `ex.a`，使用以下脚本：

```sh
create ex.a		 * 指定输出归档
addmod ex1.o ex2.o	 * 添加模块
save			 * 保存待定更改
end			 * 退出实用程序
```

## 诊断

`ranlib` 实用程序成功时退出码为 0，发生错误时大于 0。

## 参见

[ld(1)](/man1/ld.lld.1.md), archive(3), elf(3), [strftime(3)](/stdtime/strftime.3.md), [strmode(3)](/string/strmode.3.md), [ar(5)](/man5/ar.5.md)

## 标准合规性

`ranlib` 实用程序对 `-a`、`-b`、`-c`、`-i`、`-m`、`-p`、`-q`、`-r`、`-s`、`-t`、`-u`、`-v`、`-C` 和 `-T` 选项的支持被认为符合 IEEE Std 1003.2 ("POSIX.2")。

## 历史

`ranlib` 命令首次出现于 AT\&T UNIX 版本 1。在 FreeBSD 8.0 中，Kai Wang <kaiw@FreeBSD.org> 使用 libarchive 和 libelf 重新实现了 `ranlib` 和 `ranlib`。
