> 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/man1/xz.1.md).

# lzcat.1

`xz`, `unxz`, `xzcat`, `lzma`, `unlzma`, `lzcat` — 压缩或解压 `.xz` 和 `.lzma` 文件

## 名称

`xz`, `unxz`, `xzcat`, `lzma`, `unlzma`, `lzcat`

## 概要

`xz [option...] [file...]`

## 命令别名

`unxz` 等价于 `xz --decompress`。

`xzcat` 等价于 `xz --decompress --stdout`。

`lzma` 等价于 `xz --format=lzma`。

`unlzma` 等价于 `xz --format=lzma --decompress`。

`lzcat` 等价于 `xz --format=lzma --decompress --stdout`。

编写需要解压文件的脚本时，建议始终使用 `xz` 名称并附带适当的参数（`xz -d` 或 `xz -dc`），而不是使用 `unxz` 和 `xzcat` 名称。

## 描述

`xz` 是一个通用数据压缩工具，命令行语法类似于 [gzip(1)](/man/man1/gzip.1.md) 和 bzip2(1)。原生文件格式为 `.xz` 格式，但也支持 LZMA Utils 使用的传统 `.lzma` 格式以及无容器格式头的原始压缩流。此外，还支持解压 lzip 使用的 `.lz` 格式。

`xz` 根据所选的操作模式压缩或解压每个 *file*。如果未给出 *files* 或 *file* 为 `-`，`xz` 从标准输入读取并将处理后的数据写入标准输出。如果标准输出是终端，`xz` 将拒绝（显示错误并跳过该文件）将压缩数据写入标准输出。类似地，如果标准输入是终端，`xz` 将拒绝从标准输入读取压缩数据。

除非指定 `--stdout`，非 `-` 的 *files* 会被写入新文件，其名称由源 *file* 名称派生：

* 压缩时，将目标文件格式的后缀（`.xz` 或 `.lzma`）追加到源文件名以获得目标文件名。
* 解压时，从文件名中去除 `.xz`、`.lzma` 或 `.lz` 后缀以获得目标文件名。`xz` 还识别 `.txz` 和 `.tlz` 后缀，并将其替换为 `.tar` 后缀。

如果目标文件已存在，将显示错误并跳过该 *file*。

除非写入标准输出，否则如果满足以下任一条件，`xz` 将显示警告并跳过该 *file*：

* *File* 不是常规文件。符号链接不会被跟踪，因此不被视为常规文件。
* *File* 有多个硬链接。
* *File* 设置了 setuid、setgid 或粘滞位。
* 操作模式设为压缩，且 *file* 已具有目标文件格式的后缀（压缩为 `.xz` 格式时为 `.xz` 或 `.txz`，压缩为 `.lzma` 格式时为 `.lzma` 或 `.tlz`）。
* 操作模式设为解压，且 *file* 没有任何受支持文件格式的后缀（`.xz`、`.txz`、`.lzma`、`.tlz` 或 `.lz`）。

成功压缩或解压文件后，`xz` 会将所有者、组、权限、访问时间和修改时间从源 *file* 复制到目标文件。如果复制组失败，会修改权限以确保目标文件不会变得对原本无权访问源 *file* 的用户可访问。`xz` 尚不支持复制访问控制列表或扩展属性等其他元数据。

目标文件成功关闭后，除非指定了 `--keep`，否则将删除源 *file*。如果输出写入标准输出或发生错误，源 *file* 永远不会被删除。

向 `xz` 进程发送 `SIGINFO` 或 `SIGUSR1` 信号会使其向标准错误打印进度信息。这在标准错误为终端时用途有限，因为使用 `--verbose` 会显示自动更新的进度指示器。

### 内存使用

`xz` 的内存使用量从几百 KB 到几 GB 不等，取决于压缩设置。压缩文件时使用的设置决定了解压器的内存需求。通常解压器所需的内存量为压缩器创建文件时所需内存量的 5% 到 20%。例如，解压由 `xz -9` 创建的文件目前需要 65 MiB 内存。不过，也可能存在需要数 GB 内存才能解压的 `.xz` 文件。

特别是旧系统的用户可能会发现内存使用量非常大这一情况令人困扰。为防止意外，`xz` 内置了内存使用限制器，默认禁用。虽然某些操作系统提供了限制进程内存使用的方法，但依赖它被认为不够灵活（例如，使用 ulimit(1) 限制虚拟内存往往会损害 mmap(2)）。

内存使用限制器可以通过命令行选项 `--memlimit=limit` 启用。通常通过设置环境变量 `XZ_DEFAULTS` 来默认启用限制器更为方便，例如 `XZ_DEFAULTS=--memlimit=150MiB`。可以使用 `--memlimit-compress=limit` 和 `--memlimit-decompress=limit` 分别为压缩和解压设置限制。在 `XZ_DEFAULTS` 之外使用这两个选项很少有用，因为单次 `xz` 运行无法同时进行压缩和解压，而且在命令行上输入 `--memlimit=limit`（或 `-M` limit）更简短。

如果解压时超出指定的内存使用限制，`xz` 将显示错误并且解压文件失败。如果压缩时超出限制，`xz` 会尝试缩小设置以使限制不再被超出（使用 `--format=raw` 或 `--no-adjust` 时除外）。这样除非限制非常小，否则操作不会失败。设置的缩放是按不匹配压缩级别预设的步骤进行的，例如，如果限制仅略低于 `xz -9` 所需的量，设置只会稍微缩小，而不是一直降到 `xz -8`。

### `.xz` 文件的串接与填充

可以将 `.xz` 文件按原样串接。`xz` 会将此类文件当作单个 `.xz` 文件来解压。

可以在串接的部分之间或最后一个部分之后插入填充。填充必须由空字节组成，且填充的大小必须是 4 字节的倍数。例如，当 `.xz` 文件存储在以 512 字节块为单位度量文件大小的介质上时，这会很有用。

`.lzma` 文件或原始流不允许串接和填充。

## 选项

### 整数后缀和特殊值

在大多数需要整数参数的地方，支持可选后缀以方便表示大整数。整数和后缀之间不得有空格。

**`KiB`** 将整数乘以 1,024 (2^10)。`Ki`、`k`、`kB`、`K` 和 `KB` 被接受为 `KiB` 的同义词。

**`MiB`** 将整数乘以 1,048,576 (2^20)。`Mi`、`m`、`M` 和 `MB` 被接受为 `MiB` 的同义词。

**`GiB`** 将整数乘以 1,073,741,824 (2^30)。`Gi`、`g`、`G` 和 `GB` 被接受为 `GiB` 的同义词。

特殊值 `max` 可用于指示选项支持的最大整数值。

### 操作模式

如果给出多个操作模式选项，最后一个生效。

**`-z`**, **`--compress`** 压缩。当未指定操作模式选项且未从命令名暗示其他操作模式（例如 `unxz` 暗示 `--decompress`）时，这是默认操作模式。

成功压缩后，除非写入标准输出或指定了 `--keep`，否则删除源文件。

**`-d`**, **`--decompress`**, **`--uncompress`** 解压。成功解压后，除非写入标准输出或指定了 `--keep`，否则删除源文件。

**`-t`**, **`--test`** 测试压缩文件的完整性。此选项等价于 `--decompress --stdout`，但解压数据被丢弃而不是写入标准输出。不创建或删除任何文件。

**`-l`**, **`--list`** 打印有关压缩文件的信息。不产生解压输出，也不创建或删除任何文件。在列表模式下，程序无法从标准输入或其他不可寻址的源读取压缩数据。

默认列表显示文件的基本信息，每行一个文件。要获取更详细的信息，请同时使用 `--verbose` 选项。要获取更多信息，使用两次 `--verbose`，但注意这可能会很慢，因为获取所有额外信息需要多次寻址。详细输出的宽度超过 80 个字符，因此如果终端不够宽，将输出通过管道传递给例如 `less -S` 可能会很方便。

精确输出可能因 `xz` 版本和不同区域设置而异。对于机器可读的输出，应使用 `--robot --list`。

### 操作修饰符

**`-k`**, **`--keep`** 不删除输入文件。

自 `xz` 5.2.6 起，此选项还使 `xz` 即使输入是指向常规文件的符号链接、有多个硬链接或设置了 setuid、setgid 或粘滞位时也会压缩或解压。setuid、setgid 和粘滞位不会被复制到目标文件。在早期版本中，这仅通过 `--force` 完成。

**`-f`**, **`--force`** 此选项有多个效果：

* 如果目标文件已存在，在压缩或解压之前删除它。
* 即使输入是指向常规文件的符号链接、有多个硬链接或设置了 setuid、setgid 或粘滞位，也进行压缩或解压。setuid、setgid 和粘滞位不会被复制到目标文件。
* 与 `--decompress` `--stdout` 一起使用且 `xz` 无法识别源文件类型时，将源文件原样复制到标准输出。这允许 `xzcat` `--force` 像 [cat(1)](/man/man1/cat.1.md) 一样用于未经 `xz` 压缩的文件。注意，未来 `xz` 可能支持新的压缩文件格式，这可能使 `xz` 解压更多类型的文件而不是将其原样复制到标准输出。可以使用 `--format=format` 来限制 `xz` 仅解压单一文件格式。

**`-c`**, **`--stdout`**, **`--to-stdout`** 将压缩或解压的数据写入标准输出而不是文件。这暗示了 `--keep`。

**`--single-stream`** 仅解压第一个 `.xz` 流，并静默忽略流之后可能剩余的输入数据。通常此类尾部垃圾会使 `xz` 显示错误。

`xz` 从 `.lzma` 文件或原始流中解压的数据永远不会超过一个流，但此选项仍会使 `xz` 忽略 `.lzma` 文件或原始流之后可能的尾部数据。

如果操作模式不是 `--decompress` 或 `--test`，此选项无效。

自 `xz` 5.7.1alpha 起，`--single-stream` 暗示了 `--keep`。

**`--no-sparse`** 禁用稀疏文件的创建。默认情况下，如果解压到常规文件，且解压数据包含长序列的二进制零，`xz` 会尝试使文件成为稀疏文件。当写入标准输出时，只要标准输出连接到常规文件且满足某些附加条件以确保安全，此功能也同样有效。创建稀疏文件可以节省磁盘空间并通过减少磁盘 I/O 来加速解压。

**`-S`** `.suf`, **`--suffix=`** `.suf` 压缩时，使用 *.suf* 作为目标文件的后缀，而不是 `.xz` 或 `.lzma`。如果不写入标准输出且源文件已具有 .suf 后缀，则显示警告并跳过该文件。

解压时，除了具有 `.xz`、`.txz`、`.lzma`、`.tlz` 或 `.lz` 后缀的文件外，还识别具有 *.suf* 后缀的文件。如果源文件具有 .suf 后缀，则去除该后缀以获得目标文件名。

压缩或解压原始流（`--format=raw`）时，除非写入标准输出，否则必须始终指定后缀，因为原始流没有默认后缀。

**`--files`**\[**`=`**`file`] 从 *file* 读取要处理的文件名；如果省略 *file*，则从标准输入读取文件名。文件名必须以换行符终止。短横线（`-`）被视为常规文件名；它不表示标准输入。如果同时在命令行参数中给出文件名，它们会在从 *file* 读取的文件名之前处理。

**`--files0`**\[**`=`**`file`] 与 `--files[=file]` 相同，但每个文件名必须以空字符终止。

### 基本文件格式和压缩选项

**`-F`** `format`, **`--format=`** `format` 指定要压缩或解压的文件 *format*：

**`auto`** 这是默认值。压缩时，`auto` 等价于 `xz`。解压时，自动检测输入文件的格式。注意，原始流（使用 `--format=raw` 创建）无法被自动检测。

**`xz`** 压缩为 `.xz` 文件格式，或解压时仅接受 `.xz` 文件。

**`lzma`**, **`alone`** 压缩为传统 `.lzma` 文件格式，或解压时仅接受 `.lzma` 文件。备用名称 `alone` 是为了向后兼容 LZMA Utils 而提供的。

**`lzip`** 解压时仅接受 `.lz` 文件。不支持压缩。

支持 `.lz` 格式版本 0 和 1。版本 0 文件由 lzip 1.3 及更早版本生成。此类文件不常见，但可能在文件归档中找到，因为少数源代码包以此格式发布。人们也可能有此格式的旧个人文件。lzip 1.18 移除了对格式版本 0 的解压支持。lzip 1.4 及更高版本创建版本 1 格式的文件。

**`raw`** 压缩或解压原始流（无头）。这仅适用于高级用户。要解码原始流，你需要使用 `--format=raw` 并显式指定过滤器链，而该过滤器链通常会存储在容器头中。

**`-C`** `check`, **`--check=`** `check` 指定完整性检查的类型。检查从未压缩数据计算并存储在 `.xz` 文件中。此选项仅在压缩为 `.xz` 格式时有效；`.lzma` 格式不支持完整性检查。解压 `.xz` 文件时会验证完整性检查（如果有）。

支持的 *check* 类型：

**`none`** 根本不计算完整性检查。这通常是个坏主意。但当数据的完整性已通过其他方式验证时，这可能有用。

**`crc32`** 使用 IEEE-802.3（以太网）的多项式计算 CRC32。

**`crc64`** 使用 ECMA-182 的多项式计算 CRC64。这是默认值，因为它在检测损坏文件方面略优于 CRC32，且速度差异可以忽略不计。

**`sha256`** 计算 SHA-256。这比 CRC32 和 CRC64 稍慢。

`.xz` 头的完整性始终用 CRC32 验证。无法更改或禁用它。

**`--ignore-check`** 解压时不验证压缩数据的完整性检查。`.xz` 头中的 CRC32 值仍会正常验证。

**除非你知道自己在做什么，否则不要使用此选项。** 使用此选项的可能原因：

* 尝试从损坏的 .xz 文件中恢复数据。
* 加速解压。这主要对 SHA-256 或压缩得极好的文件有影响。除非文件完整性通过其他外部方式验证，否则不建议为此目的使用此选项。

**`-0`** ... **`-9`** 选择压缩预设级别。默认为 `-6`。如果指定了多个预设级别，最后一个生效。如果已指定自定义过滤器链，设置压缩预设级别会清除自定义过滤器链。

各预设之间的差异比 [gzip(1)](/man/man1/gzip.1.md) 和 bzip2(1) 更为显著。所选的压缩设置决定了解压器的内存需求，因此使用过高的预设级别可能会使在 RAM 较少的旧系统上解压文件变得困难。具体而言，**像通常对** [**gzip(1)**](/man/man1/gzip.1.md) **和 bzip2(1) 那样盲目对所有内容使用 -9 不是个好主意。**

**`-0`** ... **`-3`** 这些是相当快的预设。`-0` 有时比 `gzip -9` 更快，同时压缩效果好得多。较高级别的速度通常与 bzip2(1) 相当，压缩率相当或更好，尽管结果在很大程度上取决于被压缩数据的类型。

**`-4`** ... **`-6`** 良好到非常好的压缩，同时对旧系统也保持合理的解压器内存使用。`-6` 是默认值，通常是分发需要在仅有 16 MiB RAM 的系统上也能解压的文件的不错选择。（`-5e` 或 `-6e` 也值得考虑。参见 `--extreme`。）

**`-7`** ... **`-9`** 这些类似于 `-6`，但压缩器和解压器的内存需求更高。仅在压缩分别大于 8 MiB、16 MiB 和 32 MiB 的文件时有用。

在相同硬件上，解压速度大约是每秒恒定字节数的压缩数据。换句话说，压缩越好，解压通常越快。这也意味着每秒产生的解压输出量可能差异很大。

下表总结了各预设的特性：

| Preset | DictSize | CompCPU | CompMem | DecMem |
| :----: | :------: | :-----: | :-----: | :----: |
|   -0   |  256 KiB |    0    |  3 MiB  |  1 MiB |
|   -1   |   1 MiB  |    1    |  9 MiB  |  2 MiB |
|   -2   |   2 MiB  |    2    |  17 MiB |  3 MiB |
|   -3   |   4 MiB  |    3    |  32 MiB |  5 MiB |
|   -4   |   4 MiB  |    4    |  48 MiB |  5 MiB |
|   -5   |   8 MiB  |    5    |  94 MiB |  9 MiB |
|   -6   |   8 MiB  |    6    |  94 MiB |  9 MiB |
|   -7   |  16 MiB  |    6    | 186 MiB | 17 MiB |
|   -8   |  32 MiB  |    6    | 370 MiB | 33 MiB |
|   -9   |  64 MiB  |    6    | 674 MiB | 65 MiB |

列说明：

* DictSize 是 LZMA2 字典大小。使用比未压缩文件大小更大的字典是浪费内存。这就是为什么在没有真正需要时最好避免使用预设 `-7` ... `-9` 的原因。在 `-6` 及更低级别，浪费的内存量通常很少，无关紧要。
* CompCPU 是影响压缩速度的 LZMA2 设置的简化表示。字典大小也会影响速度，因此虽然级别 `-6` ... `-9` 的 CompCPU 相同，但更高级别仍倾向于稍慢一些。要获得更慢从而可能更好的压缩，参见 `--extreme`。
* CompMem 包含单线程模式下的压缩器内存需求。它在 `xz` 版本之间可能略有不同。
* DecMem 包含解压器内存需求。也就是说，压缩设置决定了解压器的内存需求。确切的解压器内存使用量略大于 LZMA2 字典大小，但表中的值已向上取整到下一个完整 MiB。

多线程模式的内存需求显著高于单线程模式。使用 `--block-size` 的默认值时，每个线程需要 3\*3\*DictSize 加上 CompMem 或 DecMem。例如，预设 `-6` 下四个线程需要 660-670 MiB 内存。

**`-e`**, **`--extreme`** 使用所选压缩预设级别（`-0` ... `-9`）的较慢变体，以期获得稍好的压缩率，但运气不好时也可能使压缩率变差。解压器内存使用不受影响，但在预设级别 `-0` ... `-3` 下压缩器内存使用会略有增加。

由于有两个字典大小为 4 MiB 和 8 MiB 的预设，预设 `-3e` 和 `-5e` 分别使用比 `-4e` 和 `-6e` 略快的设置（较低的 CompCPU）。这样就不会有两个预设完全相同。

| Preset | DictSize | CompCPU | CompMem | DecMem |
| :----: | :------: | :-----: | :-----: | :----: |
|   -0e  |  256 KiB |    8    |  4 MiB  |  1 MiB |
|   -1e  |   1 MiB  |    8    |  13 MiB |  2 MiB |
|   -2e  |   2 MiB  |    8    |  25 MiB |  3 MiB |
|   -3e  |   4 MiB  |    7    |  48 MiB |  5 MiB |
|   -4e  |   4 MiB  |    8    |  48 MiB |  5 MiB |
|   -5e  |   8 MiB  |    7    |  94 MiB |  9 MiB |
|   -6e  |   8 MiB  |    8    |  94 MiB |  9 MiB |
|   -7e  |  16 MiB  |    8    | 186 MiB | 17 MiB |
|   -8e  |  32 MiB  |    8    | 370 MiB | 33 MiB |
|   -9e  |  64 MiB  |    8    | 674 MiB | 65 MiB |

例如，总共有四个使用 8 MiB 字典的预设，从最快到最慢的顺序是 `-5`、`-6`、`-5e` 和 `-6e`。

**`--fast`**

**`--best`** 这些分别是 `-0` 和 `-9` 的有些误导性的别名。提供它们仅是为了向后兼容 LZMA Utils。避免使用这些选项。

**`--block-size=`** `size` 压缩为 `.xz` 格式时，将输入数据分割为 *size* 字节的块。各块相互独立压缩，这有助于多线程并使有限的随机访问解压成为可能。此选项通常用于覆盖多线程模式下的默认块大小，但也可在单线程模式下使用。

在多线程模式下，每个线程约分配三倍 *size* 字节用于缓冲输入和输出。默认 *size* 是 LZMA2 字典大小的三倍或 1 MiB，取较大者。通常一个好的值是 LZMA2 字典大小的 2-4 倍或至少 1 MiB。使用小于 LZMA2 字典大小的 *size* 是浪费 RAM，因为这样 LZMA2 字典缓冲区永远不会被完全使用。在多线程模式下，块的大小存储在块头中。此大小信息是多线程解压所必需的。

在单线程模式下，默认不进行块分割。设置此选项不影响内存使用。块头中不存储大小信息，因此在单线程模式下创建的文件与多线程模式下创建的文件不同。缺少大小信息也意味着 `xz` 将无法在多线程模式下解压这些文件。

**`--block-list=`** `items` 压缩为 `.xz` 格式时，在给定的未压缩数据间隔后开始一个新块，并可选择使用自定义过滤器链。

*items* 是逗号分隔的列表。每项由一个可选的 0 到 9 之间的过滤器链编号后跟冒号（`:`）和一个必需的未压缩数据大小组成。省略一项（两个或更多连续逗号）是使用前一项的大小和过滤器的简写。

如果输入文件大于 *items* 中大小之和，最后一项会重复直到文件结束。特殊值 `0` 可用作最后一个大小，表示文件的其余部分应编码为单个块。

每个块的备用过滤器链可与 `--filters1=filters` ... `--filters9=filters` 选项结合指定。这些选项定义了标识符为 1-9 的过滤器链。过滤器链 0 可用于引用默认过滤器链，与不指定过滤器链相同。过滤器链标识符可用于未压缩大小之前，后跟冒号（`:`）。例如，如果指定 `--block-list=1:2MiB,3:2MiB,2:4MiB,,2MiB,0:4MiB`，则将使用以下方式创建块：

* 由 `--filters1` 指定的过滤器链和 2 MiB 输入
* 由 `--filters3` 指定的过滤器链和 2 MiB 输入
* 由 `--filters2` 指定的过滤器链和 4 MiB 输入
* 由 `--filters2` 指定的过滤器链和 4 MiB 输入
* 默认过滤器链和 2 MiB 输入
* 默认过滤器链和 4 MiB 输入，直到输入结束

如果指定的大小超过编码器的块大小（线程模式下的默认值或 `--block-size=size` 指定的值），编码器将在保持 *items* 中指定的边界的同时创建额外的块。例如，如果指定 `--block-size=10MiB` `--block-list=5MiB,10MiB,8MiB,12MiB,24MiB` 且输入文件为 80 MiB，将得到 11 个块：5、10、8、10、2、10、10、4、10、10 和 1 MiB。

在多线程模式下，块的大小存储在块头中。单线程模式下不这样做，因此编码输出不会与多线程模式相同。

**`--flush-timeout=`** `timeout` 压缩时，如果自上次刷新以来已过去超过 *timeout* 毫秒（正整数）且读取更多输入会阻塞，则所有待处理的输入数据将从编码器刷新并在输出流中可用。如果 `xz` 用于压缩通过网络流式传输的数据，这会很有用。较小的 *timeout* 值使数据在接收端以较小的延迟可用，但较大的 *timeout* 值提供更好的压缩率。

此功能默认禁用。如果此选项指定多次，最后一个生效。特殊 *timeout* 值 `0` 可用于显式禁用此功能。

此功能在非 POSIX 系统上不可用。

**此功能仍处于实验阶段。** 由于 `xz` 进行缓冲的方式，目前 `xz` 不适合实时解压流。

**`--no-sync`** 在删除源文件之前，不同步目标文件及其目录到存储设备。如果压缩或解压许多小文件，这可以提高性能。但是，如果系统在删除后很快崩溃，可能目标文件未写入存储设备但删除操作已写入。在这种情况下，原始源文件和目标文件都不可用。

此选项仅在 `xz` 将要删除源文件时有效。在其他情况下，永远不会进行同步。

同步和 `--no-sync` 是在 `xz` 5.7.1alpha 中添加的。

**`--memlimit-compress=`** `limit` 为压缩设置内存使用限制。如果此选项指定多次，最后一个生效。

如果压缩设置超过 *limit*，`xz` 将尝试向下调整设置以使限制不再被超出，并显示已进行自动调整的通知。调整按以下顺序进行：减少线程数，如果多线程模式下即使一个线程也超过 *limit* 则切换到单线程模式，最后减小 LZMA2 字典大小。

使用 `--format=raw` 压缩或已指定 `--no-adjust` 时，只能减少线程数，因为这可以在不影响压缩输出的情况下完成。

如果即使经过上述调整仍无法满足 *limit*，将显示错误且 `xz` 将以退出状态 1 退出。

*limit* 可以用多种方式指定：

* *limit* 可以是以字节为单位的绝对值。使用如 `MiB` 的整数后缀会很有用。示例：`--memlimit-compress=80MiB`
* *limit* 可以指定为总物理内存（RAM）的百分比。这在共享于不同计算机之间的 shell 初始化脚本中设置 `XZ_DEFAULTS` 环境变量时特别有用。这样在内存更多的系统上限制会自动更大。示例：`--memlimit-compress=70%`
* *limit* 可以通过将其设置为 `0` 来重置为默认值。这目前等价于将 *limit* 设置为 `max`（无内存使用限制）。

对于 32 位 `xz` 有一个特殊情况：如果 *limit* 会超过 `4020 MiB`，则 *limit* 设为 `4020 MiB`。在 MIPS32 上则使用 `2000 MiB`。（值 `0` 和 `max` 不受此影响。解压不存在类似功能。）当 32 位可执行文件可以访问 4 GiB 地址空间（MIPS32 上为 2 GiB）时这会有所帮助，同时在其他情况下有望不会造成损害。

另请参见**内存使用**章节。

**`--memlimit-decompress=`** `limit` 为解压设置内存使用限制。这也影响 `--list` 模式。如果在不超出 *limit* 的情况下无法完成操作，`xz` 将显示错误并且解压文件失败。有关指定 *limit* 的可能方式，请参见 `--memlimit-compress=limit`。

**`--memlimit-mt-decompress=`** `limit` 为多线程解压设置内存使用限制。这只会影响线程数；这永远不会使 `xz` 拒绝解压文件。如果 *limit* 太低不允许任何多线程，则忽略 *limit*，`xz` 将以单线程模式继续。注意，如果同时使用 `--memlimit-decompress`，它将始终应用于单线程和多线程模式，因此多线程的有效 *limit* 永远不会高于 `--memlimit-decompress` 设置的限制。

与其他内存使用限制选项不同，`--memlimit-mt-decompress=limit` 具有系统特定的默认限制。可以使用 `xz --info-memory` 查看当前值。

此选项及其默认值的存在是因为没有任何限制时，线程化解压器可能会因某些输入文件而分配大量内存。如果你的系统上默认 *limit* 太低，可以随意增加 *limit*，但永远不要将其设置为大于可用 RAM 的值，因为对于适当的输入文件，`xz` 会尝试使用该内存量，即使线程数较少。内存耗尽或交换不会改善解压性能。

有关指定 *limit* 的可能方式，请参见 `--memlimit-compress=limit`。将 *limit* 设置为 `0` 会将 *limit* 重置为系统特定的默认值。

**`-M`** `limit`, **`--memlimit=`** `limit`, **`--memory=`** `limit` 这等价于指定 `--memlimit-compress=limit` `--memlimit-decompress=limit` `--memlimit-mt-decompress=limit`。

**`--no-adjust`** 如果不调整影响压缩输出的设置就无法满足内存使用限制，则显示错误并退出。也就是说，这阻止 `xz` 将编码器从多线程模式切换到单线程模式以及减小 LZMA2 字典大小。即使使用此选项，仍可减少线程数以满足内存使用限制，因为这不会影响压缩输出。

创建原始流（`--format=raw`）时始终禁用自动调整。

**`-T`** `threads`, **`--threads=`** `threads` 指定要使用的工作线程数。将 *threads* 设置为特殊值 `0` 使 `xz` 使用系统处理器支持的多达该数的线程。如果输入文件对于给定设置下的线程化来说不够大，或者使用更多线程会超出内存使用限制，实际线程数可能少于 *threads*。

单线程和多线程压缩器产生不同的输出。单线程压缩器会给出最小的文件大小，但只有多线程压缩器的输出可以使用多线程解压。将 *threads* 设置为 `1` 将使用单线程模式。将 *threads* 设置为任何其他值（包括 `0`）将使用多线程压缩器，即使系统仅支持一个硬件线程。（`xz` 5.2.x 在这种情况下使用单线程模式。）

要仅使用一个线程的多线程模式，将 *threads* 设置为 `+1`。`+` 前缀对 `1` 以外的值无效。除非使用 `--no-adjust`，否则内存使用限制仍可使 `xz` 切换到单线程模式。对 `+` 前缀的支持是在 `xz` 5.4.0 中添加的。

如果请求了自动线程数且未指定内存使用限制，则将使用系统特定的默认软限制来可能限制线程数。它是软限制，意义上如果线程数变为一则被忽略，因此软限制永远不会阻止 `xz` 压缩或解压。此默认软限制不会使 `xz` 从多线程模式切换到单线程模式。可以使用 `xz --info-memory` 查看活动限制。

目前唯一的线程化方法是将输入分割为块并相互独立地压缩。默认块大小取决于压缩级别，可使用 `--block-size=size` 选项覆盖。

线程化解压仅适用于包含块头中有大小信息的多个块的文件。所有在多线程模式下压缩的足够大的文件都满足此条件，但在单线程模式下压缩的文件即使使用了 `--block-size=size` 也不满足。

*threads* 的默认值为 `0`。在 `xz` 5.4.x 及更早版本中，默认值为 `1`。

### 自定义压缩器过滤器链

自定义过滤器链允许详细指定压缩设置，而不是依赖于预设关联的设置。当指定自定义过滤器链时，命令行上较早出现的预设选项（`-0` ... `-9` 和 `--extreme`）会被遗忘。如果在一个或多个自定义过滤器链选项之后指定了预设选项，新预设生效，较早指定的自定义过滤器链选项被遗忘。

过滤器链类似于命令行上的管道。压缩时，未压缩的输入进入第一个过滤器，其输出进入下一个过滤器（如果有）。最后一个过滤器的输出被写入压缩文件。链中过滤器的最大数量为四个，但通常过滤器链只有一或两个过滤器。

许多过滤器对它们在过滤器链中的位置有限制：某些过滤器只能作为链中的最后一个过滤器，某些只能作为非最后一个过滤器，某些可在链中的任何位置。根据过滤器的不同，此限制要么是过滤器设计固有的，要么是为了防止安全问题而存在。

可以用两种不同方式指定自定义过滤器链。`--filters=filters` 和 `--filters1=filters` ... `--filters9=filters` 选项允许使用 liblzma 过滤器字符串语法在单个选项中指定整个过滤器链。或者，可以通过按所需顺序使用一个或多个单独的过滤器选项来指定过滤器链。也就是说，单独过滤器选项的顺序是重要的！解码原始流（`--format=raw`）时，过滤器链必须按压缩时指定的相同顺序指定。在完整链选项（`--filters=filters`）之前指定的任何单独过滤器或预设选项将被遗忘。在完整链选项之后指定的单独过滤器将重置过滤器链。

完整和单独过滤器选项都接受以逗号分隔列表形式的过滤器特定 *options*。*options* 中的额外逗号被忽略。每个选项都有默认值，因此只需指定你想更改的。

要查看整个过滤器链和 *options*，使用 `xz -vv`（即使用两次 `--verbose`）。这也适用于查看预设使用的过滤器链选项。

**`--filters=`** `filters` 在单个选项中指定完整过滤器链或预设。每个过滤器可以用空格或两个短横线（`--`）分隔。*filters* 在 shell 命令行上可能需要加引号以便被解析为单个选项。要表示 *options*，使用 `:` 或 `=`。预设可以加前缀 `-` 并后跟零个或多个标志。唯一支持的标志是 `e`，用于应用与 `--extreme` 相同的选项。

**`--filters1=`** `filters` ... **`--filters9=`** `filters` 指定最多九个可与 `--block-list` 一起使用的附加过滤器链。

例如，在压缩包含可执行文件后跟文本文件的归档时，可执行文件部分可以使用带 BCJ 过滤器的过滤器链，而文本部分仅使用 LZMA2 过滤器。

**`--filters-help`** 显示描述如何在 `--filters` 和 `--filters1=filters` ... `--filters9=filters` 选项中指定预设和自定义过滤器链的帮助信息，并成功退出。

**`--lzma1`**\[**`=`**`options`]

**`--lzma2`**\[**`=`**`options`] 将 LZMA1 或 LZMA2 过滤器添加到过滤器链。这些过滤器只能用作链中的最后一个过滤器。

LZMA1 是传统过滤器，几乎仅因传统的 `.lzma` 文件格式（仅支持 LZMA1）而受支持。LZMA2 是 LZMA1 的更新版本，修复了 LZMA1 的一些实际问题。`.xz` 格式使用 LZMA2，完全不支持 LZMA1。LZMA1 和 LZMA2 的压缩速度和压缩率实际上相同。

LZMA1 和 LZMA2 共享同一组 *options*：

*`preset=`* `preset` 将所有 LZMA1 或 LZMA2 *options* 重置为 *preset*。*Preset* 由一个整数组成，后可跟单字母预设修饰符。整数可以是 `0` 到 `9`，对应命令行选项 `-0` ... `-9`。目前唯一支持的修饰符是 `e`，对应 `--extreme`。如果未指定 `preset`，LZMA1 或 LZMA2 *options* 的默认值取自预设 `6`。

*`dict=`* `size` 字典（历史缓冲区）*size* 指示内存中保留的最近处理的未压缩数据的字节数。算法尝试在未压缩数据中查找重复字节序列（匹配），并用对字典中当前数据的引用替换它们。字典越大，找到匹配的机会越高。因此，增大字典 *size* 通常会改善压缩率，但比未压缩文件更大的字典是浪费内存。

典型字典 *size* 从 64 KiB 到 64 MiB。最小为 4 KiB。压缩的最大值目前为 1.5 GiB（1536 MiB）。解压器已支持最多比 4 GiB 少一个字节的字典，这是 LZMA1 和 LZMA2 流格式的最大值。

字典 *size* 和匹配查找器（mf）共同决定 LZMA1 或 LZMA2 编码器的内存使用。解压需要与压缩时相同（或更大）的字典 *size*，因此解码器的内存使用由压缩时使用的字典大小决定。`.xz` 头将字典 *size* 存储为 2^n 或 2^n + 2^(n-1)，因此这些 *size* 在压缩时略受青睐。其他 *size* 在存储到 `.xz` 头时会向上取整。

*`lc=`* `lc` 指定字面上下文位数。最小为 0，最大为 4；默认为 3。此外，*lc* 和 *lp* 之和不得超过 4。

所有无法编码为匹配的字节都编码为字面量。也就是说，字面量就是一次编码一个的 8 位字节。

字面编码假设前一个未压缩字节的最高 *lc* 位与下一个字节相关。例如，在典型的英文文本中，大写字母后面通常跟着小写字母，而小写字母通常后面跟着另一个小写字母。在 US-ASCII 字符集中，大写字母的最高三位是 010，小写字母是 011。当 *lc* 至少为 3 时，字面编码可以利用未压缩数据中的这一特性。

默认值 (3) 通常很好。如果要最大压缩，测试 `lc=4`。有时它有一点帮助，有时它使压缩更差。如果它使压缩更差，也测试 `lc=2`。

*`lp=`* `lp` 指定字面位置位数。最小为 0，最大为 4；默认为 0。

*Lp* 影响编码字面量时假设未压缩数据中的对齐方式。有关对齐的更多信息，请参见下面的 *pb*。

*`pb=`* `pb` 指定位置位数。最小为 0，最大为 4；默认为 2。

*Pb* 影响一般假设的未压缩数据中的对齐方式。默认值表示四字节对齐（2^pb =2^2=4），当没有更好的猜测时这通常是不错的选择。

当已知对齐方式时，相应地设置 *pb* 可能会稍微减小文件大小。例如，对于具有一字节对齐的文本文件（US-ASCII、ISO-8859-\*、UTF-8），设置 `pb=0` 可以稍微改善压缩。对于 UTF-16 文本，`pb=1` 是不错的选择。如果对齐是奇数如 3 字节，`pb=0` 可能是最佳选择。

尽管假设的对齐可以通过 *pb* 和 lp 调整，LZMA1 和 LZMA2 仍然略微偏向 16 字节对齐。在设计可能经常用 LZMA1 或 LZMA2 压缩的文件格式时可能值得考虑这一点。

*`mf=`* `mf` 匹配查找器对编码器速度、内存使用和压缩率有重大影响。通常哈希链匹配查找器比二叉树匹配查找器更快。默认值取决于预设：0 使用 `hc3`，1-3 使用 `hc4`，其余使用 `bt4`。

支持以下匹配查找器。下面的内存使用公式是粗略近似值，当 *dict* 是 2 的幂时最接近实际。

**`hc3`** 具有 2 字节和 3 字节哈希的哈希链 *nice* 的最小值：3 内存使用： *dict* \* 7.5（如果 *dict* <= 16 MiB）； *dict* \* 5.5 + 64 MiB（如果 *dict* > 16 MiB）

**`hc4`** 具有 2、3 和 4 字节哈希的哈希链 *nice* 的最小值：4 内存使用： *dict* \* 7.5（如果 *dict* <= 32 MiB）； *dict* \* 6.5（如果 *dict* > 32 MiB）

**`bt2`** 具有 2 字节哈希的二叉树 *nice* 的最小值：2 内存使用：*dict* \* 9.5

**`bt3`** 具有 2 和 3 字节哈希的二叉树 *nice* 的最小值：3 内存使用： *dict* \* 11.5（如果 *dict* <= 16 MiB）； *dict* \* 9.5 + 64 MiB（如果 *dict* > 16 MiB）

**`bt4`** 具有 2、3 和 4 字节哈希的二叉树 *nice* 的最小值：4 内存使用： *dict* \* 11.5（如果 *dict* <= 32 MiB）； *dict* \* 10.5（如果 *dict* > 32 MiB）

*`mode=`* `mode` 压缩 *mode* 指定分析匹配查找器产生的数据的方法。支持的 *modes* 是 `fast` 和 `normal`。预设 0-3 的默认值为 `fast`，预设 4-9 的默认值为 `normal`。

通常 `fast` 与哈希链匹配查找器一起使用，`normal` 与二叉树匹配查找器一起使用。这也是预设所做的。

*`nice=`* `nice` 指定什么被认为是匹配的不错长度。一旦找到至少 *nice* 字节的匹配，算法停止寻找可能更好的匹配。

*Nice* 可以是 2-273 字节。较高的值倾向于以牺牲速度为代价提供更好的压缩率。默认值取决于 *preset*。

*`depth=`* `depth` 指定匹配查找器中的最大搜索深度。默认值为特殊值 0，使压缩器从 *mf* 和 *nice* 确定合理的 *depth*。

哈希链的合理 *depth* 为 4-100，二叉树为 16-1000。对 *depth* 使用非常高的值可能使编码器对某些文件极其缓慢。除非你准备在压缩耗时过长时中断压缩，否则避免将 *depth* 设置为超过 1000。

解码原始流（`--format=raw`）时，LZMA2 仅需要字典大小。LZMA1 还需要 lc、lp 和 pb。

**`--x86`**\[**`=`**`options`]

**`--arm`**\[**`=`**`options`]

**`--armthumb`**\[**`=`**`options`]

**`--arm64`**\[**`=`**`options`]

**`--powerpc`**\[**`=`**`options`]

**`--ia64`**\[**`=`**`options`]

**`--sparc`**\[**`=`**`options`]

**`--riscv`**\[**`=`**`options`] 将分支/调用/跳转（BCJ）过滤器添加到过滤器链。这些过滤器只能用作过滤器链中的非最后一个过滤器。

BCJ 过滤器将机器码中的相对地址转换为其绝对对应物。这不改变数据大小，但增加了冗余，这可以帮助 LZMA2 产生小 0-15% 的 `.xz` 文件。BCJ 过滤器始终可逆，因此对错误类型的数据使用 BCJ 过滤器不会造成任何数据丢失，尽管可能使压缩率略差。BCJ 过滤器非常快且使用微不足道的内存量。

这些 BCJ 过滤器在压缩率方面有已知问题：

* 某些类型的包含可执行代码的文件（例如，目标文件、静态库和 Linux 内核模块）的指令中的地址被填充值填充。这些 BCJ 过滤器仍会进行地址转换，这会使这些文件的压缩更差。
* 如果将 BCJ 过滤器应用于归档，可能使压缩率比不使用 BCJ 过滤器更差。例如，如果存在相似甚至相同的可执行文件，过滤可能会使文件不那么相似，从而压缩更差。同一归档中非可执行文件的内容也可能有影响。实际上，必须尝试使用和不使用 BCJ 过滤器以查看每种情况下哪个更好。

不同指令集有不同的对齐方式：可执行文件在输入数据中必须对齐到此值的倍数才能使过滤器工作。

|   Filter  | Alignment |      Notes     |
| :-------: | :-------: | :------------: |
|    x86    |     1     | 32 位或 64 位 x86 |
|    ARM    |     4     |                |
| ARM-Thumb |     2     |                |
|   ARM64   |     4     |   4096 字节对齐最佳  |
|  PowerPC  |     4     |      仅大端序      |
|   IA-64   |     16    |     Itanium    |
|   SPARC   |     4     |                |
|   RISC-V  |     2     |                |

由于 BCJ 过滤后的数据通常用 LZMA2 压缩，如果 LZMA2 选项设置为匹配所选 BCJ 过滤器的对齐方式，压缩率可能会略有改善。示例：

* IA-64 过滤器具有 16 字节对齐，因此 `pb=4,lp=4,lc=0` 与 LZMA2 配合良好 (2^4=16)。
* RISC-V 代码根据文件是否包含 16 位压缩指令（C 扩展）而具有 2 字节或 4 字节对齐。使用 16 位指令时，`pb=2,lp=1,lc=3` 或 `pb=1,lp=1,lc=3` 较好。不使用 16 位指令时，`pb=2,lp=2,lc=2` 最佳。可以使用 `readelf -h` 检查 "Flags" 行是否出现 "RVC"。
* ARM64 始终为 4 字节对齐，因此 `pb=2,lp=2,lc=2` 最佳。
* x86 过滤器是个例外。压缩 x86 可执行文件时，通常最好坚持使用 LZMA2 的默认值（`pb=2,lp=0,lc=3`）。

所有 BCJ 过滤器支持相同的 *options*：

*`start=`* `offset` 指定在相对地址和绝对地址之间转换时使用的起始 *offset*。*offset* 必须是过滤器对齐方式（见上表）的倍数。默认为零。实际上，默认值就很好；指定自定义 *offset* 几乎从未有用。

**`--delta`**\[**`=`**`options`] 将 Delta 过滤器添加到过滤器链。Delta 过滤器只能用作过滤器链中的非最后一个过滤器。

目前仅支持简单的按字节 delta 计算。它在压缩例如未压缩的位图图像或未压缩的 PCM 音频时可能有用。但是，专用算法可能比 Delta + LZMA2 给出明显更好的结果。对于音频尤其如此，例如使用 flac(1) 压缩得更快更好。

支持的 *options*：

*`dist=`* `distance` 以字节为单位指定 delta 计算的 *distance*。*distance* 必须为 1-256。默认为 1。

例如，`dist=2` 和八字节输入 A1 B1 A2 B3 A3 B5 A4 B7，输出将为 A1 B1 01 02 01 02 01 02。

### 其他选项

**`-q`**, **`--quiet`** 抑制警告和通知。指定两次以也抑制错误。此选项对退出状态没有影响。也就是说，即使警告被抑制，指示警告的退出状态仍会被使用。

**`-v`**, **`--verbose`** 详尽输出。如果标准错误连接到终端，`xz` 将显示进度指示器。指定两次 `--verbose` 会给出更详尽的输出。

进度指示器显示以下信息：

* 如果输入文件大小已知，则显示完成百分比。也就是说，百分比无法在管道中显示。
* 已产生的压缩数据量（压缩）或已消耗的压缩数据量（解压）。
* 已消耗的未压缩数据量（压缩）或已产生的未压缩数据量（解压）。
* 压缩率，通过将迄今为止处理的压缩数据量除以迄今为止处理的未压缩数据量来计算。
* 压缩或解压速度。以每秒消耗（压缩）或产生（解压）的未压缩数据量来度量。它在 `xz` 开始处理文件后几秒钟才显示。
* 经过时间，格式为 M:SS 或 H:MM:SS。
* 预计剩余时间仅在输入文件大小已知且自 `xz` 开始处理文件以来已过去几秒钟时显示。时间以不太精确的格式显示，永远不会有任何冒号，例如 2 min 30 s。

当标准错误不是终端时，`--verbose` 会使 `xz` 在压缩或解压文件后向标准错误以单行打印文件名、压缩大小、未压缩大小、压缩率，可能还有速度和经过时间。速度和经过时间仅在操作花费至少几秒钟时才包含。如果操作未完成（例如由于用户中断），且输入文件大小已知，还会打印完成百分比。

**`-Q`**, **`--no-warn`** 即使检测到值得警告的情况，也不将退出状态设为 2。此选项不影响详尽级别，因此要既不显示警告又不改变退出状态，需要同时使用 `--quiet` 和 `--no-warn`。

**`--robot`** 以机器可解析的格式打印消息。这旨在简化想要使用 `xz` 而非 liblzma 的前端的编写，各种脚本可能就是这种情况。启用此选项的输出旨在跨 `xz` 版本稳定。详情参见**ROBOT 模式**章节。

**`--info-memory`** 以人类可读格式显示 `xz` 认为系统拥有的物理内存（RAM）量和处理器线程数，以及压缩和解压的内存使用限制，并成功退出。

**`-h`**, **`--help`** 显示描述最常用选项的帮助信息，并成功退出。

**`-H`**, **`--long-help`** 显示描述 `xz` 所有功能的帮助信息，并成功退出。

**`-V`**, **`--version`** 以人类可读格式显示 `xz` 和 liblzma 的版本号。要获得机器可解析的输出，在 `--version` 之前指定 `--robot`。

## ROBOT 模式

robot 模式通过 `--robot` 选项激活。它使 `xz` 的输出更容易被其他程序解析。目前 `--robot` 仅与 `--list`、`--filters-help`、`--info-memory` 和 `--version` 一起支持。未来将支持用于压缩和解压。

### 列表模式

`xz --robot --list` 使用制表符分隔的输出。每行的第一列有一个字符串指示该行上找到的信息类型：

**`name`** 这始终是开始列出文件时的第一行。该行的第二列是文件名。

**`file`** 此行包含有关 `.xz` 文件的整体信息。此行始终在 `name` 行之后打印。

**`stream`** 此行类型仅在指定 `--verbose` 时使用。`.xz` 文件中有多少个流就有多少个 `stream` 行。

**`block`** 此行类型仅在指定 `--verbose` 时使用。`.xz` 文件中有多少个块就有多少个 `block` 行。`block` 行在所有 `stream` 行之后显示；不同行类型不交错。

**`summary`** 此行类型仅在指定两次 `--verbose` 时使用。此行在所有 `block` 行之后打印。与 `file` 行一样，`summary` 行包含有关 `.xz` 文件的整体信息。

**`totals`** 此行始终是列表输出的最后一行。它显示总计计数和大小。

`file` 行的列：

2. 文件中的流数
3. 流中的块总数
4. 文件的压缩大小
5. 文件的未压缩大小
6. 压缩率，例如 `0.123`。如果比率超过 9.999，则显示三个短横线（`---`）而不是比率。
7. 以逗号分隔的完整性检查名称列表。已知检查类型使用以下字符串：`None`、`CRC32`、`CRC64` 和 `SHA-256`。对于未知检查类型，使用 *Unknown-N*，其中 *N* 是以十进制数（一位或两位数字）表示的 Check ID。
8. 文件中流填充的总大小

`stream` 行的列：

2. 流号（第一个流为 1）
3. 流中的块数
4. 压缩起始偏移量
5. 未压缩起始偏移量
6. 压缩大小（不包括流填充）
7. 未压缩大小
8. 压缩率
9. 完整性检查名称
10. 流填充大小

`block` 行的列：

2. 包含此块的流号
3. 相对于流开头的块号（第一个块为 1）
4. 相对于文件开头的块号
5. 相对于文件开头的压缩起始偏移量
6. 相对于文件开头的未压缩起始偏移量
7. 块的总压缩大小（包括头）
8. 未压缩大小
9. 压缩率
10. 完整性检查名称

如果指定了两次 `--verbose`，`block` 行上将包含附加列。这些在单次 `--verbose` 时不显示，因为获取此信息需要多次寻址，因此可能很慢：

11. 完整性检查的十六进制值
12. 块头大小
13. 块标志：`c` 表示存在压缩大小，`u` 表示存在未压缩大小。如果未设置标志，则显示短横线（`-`）以保持字符串长度固定。未来可能会在字符串末尾添加新标志。
14. 块中实际压缩数据的大小（不包括块头、块填充和检查字段）
15. 使用此 `xz` 版本解压此块所需的内存量（以字节为单位）
16. 过滤器链。注意，压缩时使用的大多数选项无法知道，因为 `.xz` 头中仅存储解压所需的选项。

`summary` 行的列：

2. 使用此 `xz` 版本解压此文件所需的内存量（以字节为单位）
3. `yes` 或 `no`，指示是否所有块头都存储了压缩大小和未压缩大小

*自* `xz` *5.1.2alpha 起：*

4. 解压文件所需的最低 `xz` 版本

`totals` 行的列：

2. 流数
3. 块数
4. 压缩大小
5. 未压缩大小
6. 平均压缩率
7. 文件中出现的以逗号分隔的完整性检查名称列表
8. 流填充大小
9. 文件数。这是为了保持前面列的顺序与 `file` 行相同。

如果指定了两次 `--verbose`，`totals` 行上将包含附加列：

10. 使用此 `xz` 版本解压文件所需的最大内存量（以字节为单位）
11. `yes` 或 `no`，指示是否所有块头都存储了压缩大小和未压缩大小

*自* `xz` *5.1.2alpha 起：*

12. 解压文件所需的最低 `xz` 版本

未来版本可能添加新行类型，并且可以向现有行类型添加新列，但现有列不会被更改。

### 过滤器帮助

`xz --robot --filters-help` 按以下格式打印支持的过滤器：

```sh
filter:option=<value>,option=<value>...
```

*filter* 过滤器名称

*option* 过滤器特定选项名称

*value* 数值 *value* 范围显示为 。字符串 *value* 选项显示在 **< >** 中，以 **|** 字符分隔。

每个过滤器单独打印在一行上。

### 内存限制信息

`xz --robot --info-memory` 打印单行，包含多个制表符分隔的列：

1. 物理内存（RAM）总量（以字节为单位）。
2. 压缩的内存使用限制（以字节为单位）（`--memlimit-compress`）。特殊值 `0` 表示默认设置，对于单线程模式，这等同于无限制。
3. 解压的内存使用限制（以字节为单位）（`--memlimit-decompress`）。特殊值 `0` 表示默认设置，对于单线程模式，这等同于无限制。
4. 自 `xz` 5.3.4alpha 起：多线程解压的内存使用限制（以字节为单位）（`--memlimit-mt-decompress`）。这从不为零，因为如果未显式指定限制，则使用第 5 列中显示的系统特定默认值。这也从不大于第 3 列中的值，即使已使用 `--memlimit-mt-decompress` 指定了更大的值。
5. 自 `xz` 5.3.4alpha 起：系统特定的默认内存使用限制，用于在使用自动线程数压缩（`--threads=0`）且未指定内存使用限制（`--memlimit-compress`）时限制线程数。这也用作 `--memlimit-mt-decompress` 的默认值。
6. 自 `xz` 5.3.4alpha 起：可用处理器线程数。

未来，`xz --robot --info-memory` 的输出可能有更多列，但永远不会超过单行。

### 版本

`xz --robot --version` 按以下格式打印 `xz` 和 liblzma 的版本号：

*XZ\_VERSION=* `XYYYZZZS`

*LIBLZMA\_VERSION=* `XYYYZZZS`

*X* 主版本号。

*YYY* 次版本号。偶数为稳定版。奇数为 alpha 或 beta 版本。

*ZZZ* 稳定版本的补丁级别，或仅开发版本的计数器。

*S* 稳定性。0 为 alpha，1 为 beta，2 为稳定。*YYY* 为偶数时 *S* 应始终为 2。

如果 `xz` 和 liblzma 来自相同的 XZ Utils 发行版，两行上的 *XYYYZZZS* 相同。

示例：4.999.9beta 是 `49990091`，5.0.0 是 `50000002`。

## 退出状态

**0** 一切正常。

**1** 发生错误。

**2** 出现值得警告的情况，但未发生实际错误。

在标准错误上打印的通知（非警告或错误）不影响退出状态。

## 环境变量

`xz` 按此顺序从环境变量 `XZ_DEFAULTS` 和 `XZ_OPT` 解析以空格分隔的选项列表，在解析命令行选项之前。注意，仅从环境变量解析选项；所有非选项都被静默忽略。解析使用 getopt\_long(3) 完成，命令行参数也使用此函数。

**警告：** 通过设置这些环境变量，实际上是在修改运行 `xz` 的程序和脚本。大多数情况下，通过环境变量设置内存使用限制、线程数和压缩选项是安全的。但是，某些选项可能会破坏脚本。一个明显的例子是 `--help`，它使 `xz` 显示帮助文本而不是压缩或解压文件。更微妙的例子是 `--quiet` 和 `--verbose`。在许多情况下，使用 `--verbose` 启用进度指示器效果很好，但在某些情况下，额外消息会产生问题。详尽级别还会影响 `--list` 的行为。

**`XZ_DEFAULTS`** 用户特定或系统范围的默认选项。通常在 shell 初始化脚本中设置，以默认启用 `xz` 的内存使用限制器或设置默认线程数。除 shell 初始化脚本和类似特殊情况外，脚本永远不应设置或取消设置 `XZ_DEFAULTS`。

**`XZ_OPT`** 用于在无法直接在 `xz` 命令行上设置选项时向 `xz` 传递选项。当 `xz` 由脚本或工具运行时就是这种情况，例如 GNU tar(1)：

```sh
XZ_OPT=-2v tar caf foo.tar.xz foo
```

脚本可以使用 `XZ_OPT`，例如，设置脚本特定的默认压缩选项。仍然建议如果合理的话允许用户覆盖 `XZ_OPT`。例如，在 [sh(1)](/man/man1/sh.1.md) 脚本中可以使用类似以下的内容：

```sh
XZ_OPT=${XZ_OPT-"-7e"}
export XZ_OPT
```

## LZMA UTILS 兼容性

`xz` 的命令行语法实际上是 LZMA Utils 4.32.x 中找到的 `lzma`、`unlzma` 和 `lzcat` 的超集。在大多数情况下，可以用 XZ Utils 替换 LZMA Utils 而不会破坏现有脚本。但存在一些不兼容性，有时可能导致问题。

### 压缩预设级别

`xz` 和 LZMA Utils 中的压缩级别预设编号不完全相同。最重要的区别是字典大小如何映射到不同预设。字典大小大致等于解压器内存使用。

| Level |   `xz`  | LZMA Utils |
| :---: | :-----: | :--------: |
|   -0  | 256 KiB |     N/A    |
|   -1  |  1 MiB  |   64 KiB   |
|   -2  |  2 MiB  |    1 MiB   |
|   -3  |  4 MiB  |   512 KiB  |
|   -4  |  4 MiB  |    1 MiB   |
|   -5  |  8 MiB  |    2 MiB   |
|   -6  |  8 MiB  |    4 MiB   |
|   -7  |  16 MiB |    8 MiB   |
|   -8  |  32 MiB |   16 MiB   |
|   -9  |  64 MiB |   32 MiB   |

字典大小差异也影响压缩器内存使用，但 LZMA Utils 和 XZ Utils 之间还有其他一些差异，使差异更大：

| Level |   `xz`  | LZMA Utils 4.32.x |
| :---: | :-----: | :---------------: |
|   -0  |  3 MiB  |        N/A        |
|   -1  |  9 MiB  |       2 MiB       |
|   -2  |  17 MiB |       12 MiB      |
|   -3  |  32 MiB |       12 MiB      |
|   -4  |  48 MiB |       16 MiB      |
|   -5  |  94 MiB |       26 MiB      |
|   -6  |  94 MiB |       45 MiB      |
|   -7  | 186 MiB |       83 MiB      |
|   -8  | 370 MiB |      159 MiB      |
|   -9  | 674 MiB |      311 MiB      |

LZMA Utils 中的默认预设级别为 `-7`，而 XZ Utils 中为 `-6`，因此两者默认都使用 8 MiB 字典。

### 流式与非流式 `.lzma` 文件

文件的未压缩大小可以存储在 `.lzma` 头中。LZMA Utils 在压缩常规文件时这样做。另一种方法是标记未压缩大小为未知，并使用有效载荷结束标记指示解压器应在哪里停止。LZMA Utils 在未压缩大小未知时使用此方法，例如在管道中。

`xz` 支持解压带或不带有效载荷结束标记的 `.lzma` 文件，但 `xz` 创建的所有 `.lzma` 文件都将使用有效载荷结束标记，并在 `.lzma` 头中将未压缩大小标记为未知。在某些不常见的情况下，这可能是个问题。例如，嵌入式设备中的 `.lzma` 解压器可能仅适用于具有已知未压缩大小的文件。如果遇到此问题，你需要使用 LZMA Utils 或 LZMA SDK 来创建具有已知未压缩大小的 `.lzma` 文件。

### 不支持的 `.lzma` 文件

`.lzma` 格式允许 *lc* 值最大为 8，*lp* 值最大为 4。LZMA Utils 可以解压任何 *lc* 和 lp 的文件，但始终创建 `lc=3` 和 `lp=0` 的文件。使用 `xz` 和 LZMA SDK 可以创建具有其他 *lc* 和 *lp* 的文件。

liblzma 中 LZMA1 过滤器的实现要求 *lc* 和 *lp* 之和不得超过 4。因此，超过此限制的 `.lzma` 文件无法用 `xz` 解压。

LZMA Utils 仅创建字典大小为 2^n（2 的幂）的 `.lzma` 文件，但接受任何字典大小的文件。liblzma 仅接受字典大小为 2^n 或 2^n + 2^(n-1) 的 `.lzma` 文件。这是为了减少检测 `.lzma` 文件时的误报。

这些限制在实践中不应该是问题，因为几乎所有 `.lzma` 文件都是用 liblzma 会接受的设置压缩的。

### 尾部垃圾

解压时，LZMA Utils 静默忽略第一个 `.lzma` 流之后的所有内容。在大多数情况下，这是一个 bug。这也意味着 LZMA Utils 不支持解压串接的 `.lzma` 文件。

如果第一个 `.lzma` 流之后还有数据，除非使用了 `--single-stream`，否则 `xz` 认为文件已损坏。这可能会破坏那些假设尾部垃圾被忽略的不常见脚本。

## 注意事项

### 压缩输出可能不同

即使压缩选项相同，不同 XZ Utils 版本从相同未压缩输入文件产生的确切压缩输出可能不同。这是因为可以在不影响文件格式的情况下改进编码器（更快或更好的压缩）。如果使用不同的构建选项，即使同一 XZ Utils 版本的不同构建之间输出也可能不同。

上述意味着一旦实现了 `--rsyncable`，除非旧文件和新文件都是用相同 xz 版本压缩的，否则生成的文件不一定是 rsyncable 的。如果冻结编码器实现的一部分以保持 rsyncable 输出跨 xz 版本稳定，则可以修复此问题。

### 嵌入式 `.xz` 解压器

像 XZ Embedded 这样的嵌入式 `.xz` 解压器实现不一定支持以 `none` 和 `crc32` 之外的完整性 *check* 类型创建的文件。由于默认值为 `--check=crc64`，创建用于嵌入式系统的文件时必须使用 `--check=none` 或 `--check=crc32`。

在嵌入式系统之外，所有 `.xz` 格式解压器都支持所有 *check* 类型，或者至少能够在不支持特定 *check* 时在不验证完整性检查的情况下解压文件。

XZ Embedded 支持 BCJ 过滤器，但仅使用默认起始偏移量。

## 实例

### 基础

使用默认压缩级别（`-6`）将文件 *foo* 压缩为 *foo.xz*，如果压缩成功则删除 *foo*：

```sh
xz foo
```

将 *bar.xz* 解压为 *bar*，即使解压成功也不删除 *bar.xz*：

```sh
xz -dk bar.xz
```

使用预设 `-4e`（`-4 --extreme`）创建 *baz.tar.xz*，这比默认的 `-6` 慢，但压缩和解压所需的内存更少（分别为 48 MiB 和 5 MiB）：

```sh
tar cf - baz | xz -4e > baz.tar.xz
```

可以使用单个命令将压缩和未压缩文件的混合解压到标准输出：

```sh
xz -dcf a.txt b.txt.xz c.txt d.txt.lzma > abcd.txt
```

### 多文件并行压缩

在 GNU 和 \*BSD 上，可以使用 [find(1)](/man/man1/find.1.md) 和 [xargs(1)](/man/man1/xargs.1.md) 来并行化许多文件的压缩：

```sh
find . -type f \! -name '*.xz' -print0 \
  | xargs -0r -P4 -n16 xz -T1
```

[xargs(1)](/man/man1/xargs.1.md) 的 `-P` 选项设置并行 `xz` 进程数。`-n` 选项的最佳值取决于要压缩的文件数量。如果只有几个文件，该值可能应该是 1；如果有数万个文件，100 甚至更多可能适合减少 [xargs(1)](/man/man1/xargs.1.md) 最终将创建的 `xz` 进程数。

`xz` 的 `-T1` 选项用于强制其进入单线程模式，因为 [xargs(1)](/man/man1/xargs.1.md) 用于控制并行化量。

### Robot 模式

计算压缩多个文件后总共节省了多少字节：

```sh
xz --robot --list *.xz | awk '/^totals/{print $5-$4}'
```

脚本可能想知道它使用的是否是足够新的 `xz`。以下 [sh(1)](/man/man1/sh.1.md) 脚本检查 `xz` 工具的版本号至少为 5.0.0。此方法兼容不支持 `--robot` 选项的旧 beta 版本：

```sh
if ! eval "$(xz --robot --version 2> /dev/null)" || \
   [ "$XZ_VERSION" -lt 50000002 ]; then
  echo "Your xz is too old."
fi
unset XZ_VERSION LIBLZMA_VERSION
```

使用 `XZ_OPT` 为解压设置内存使用限制，但如果已设置了限制，则不增加它：

```sh
NEWLIM=$((123 << 20))  # 123 MiB
OLDLIM=$(xz --robot --info-memory | cut -f3)
if [ $OLDLIM -eq 0 -o $OLDLIM -gt $NEWLIM ]; then
  XZ_OPT="$XZ_OPT --memlimit-decompress=$NEWLIM"
  export XZ_OPT
fi
```

### 自定义压缩器过滤器链

自定义过滤器链最简单的用途是自定义 LZMA2 预设。这可能很有用，因为预设仅覆盖了潜在有用的压缩设置组合的子集。

选项 `-0` ... `-9` 和 `--extreme` 描述中表格的 CompCPU 列在自定义 LZMA2 预设时很有用。以下是从这两个表格中收集的相关部分：

| Preset | CompCPU |
| :----: | :-----: |
|   -0   |    0    |
|   -1   |    1    |
|   -2   |    2    |
|   -3   |    3    |
|   -4   |    4    |
|   -5   |    5    |
|   -6   |    6    |
|   -5e  |    7    |
|   -6e  |    8    |

如果你知道一个文件需要相当大的字典（例如 32 MiB）才能很好压缩，但你希望比 `xz -8` 压缩得更快，可以修改低 CompCPU 值（例如 1）的预设以使用更大的字典：

```sh
xz --lzma2=preset=1,dict=32MiB foo.tar
```

对于某些文件，上述命令可能比 `xz -6` 更快，同时压缩效果显著更好。但是，必须强调的是，只有某些文件能从大字典中受益，同时保持低 CompCPU 值。大字典可以大有帮助的最明显情况是包含至少几兆字节的非常相似文件的归档。字典大小必须明显大于任何单个文件，以允许 LZMA2 充分利用连续文件之间的相似性。

如果非常高的压缩器和解压器内存使用没问题，并且被压缩的文件至少有几百兆字节，使用比 `xz -9` 将使用的 64 MiB 更大的字典可能有用：

```sh
xz -vv --lzma2=dict=192MiB big_foo.tar
```

像上面示例中那样使用 `-vv`（`--verbose --verbose`）可以有助于查看压缩器和解压器的内存需求。记住，使用比未压缩文件大小更大的字典是浪费内存，因此上述命令对小文件无用。

有时压缩时间不重要，但解压器内存使用必须保持低，例如为了使文件能够在嵌入式系统上解压。以下命令使用 `-6e`（`-6 --extreme`）作为基础，并将字典仅设置为 64 KiB。生成的文件可以用 XZ Embedded（这就是为什么有 `--check=crc32`）使用约 100 KiB 内存解压：

```sh
xz --check=crc32 --lzma2=preset=6e,dict=64KiB foo
```

如果你想尽可能多地挤出字节，调整字面上下文位数（lc）和位置位数（pb）有时会有帮助。调整字面位置位数（lp）也可能有帮助，但通常 *lc* 和 *pb* 更重要。例如，源代码归档主要包含 US-ASCII 文本，因此类似以下的内容可能给出比 `xz -6e` 略小（如 0.1%）的文件（也尝试不带 `lc=4`）：

```sh
xz --lzma2=preset=6e,pb=0,lc=4 source_code.tar
```

将另一个过滤器与 LZMA2 一起使用可以改善某些文件类型的压缩。例如，要使用 x86 BCJ 过滤器压缩 x86-32 或 x86-64 共享库：

```sh
xz --x86 --lzma2 libfoo.so
```

注意，过滤器选项的顺序是重要的。如果在 `--lzma2` 之后指定 `--x86`，`xz` 将给出错误，因为 LZMA2 之后不能有任何过滤器，也因为 x86 BCJ 过滤器不能用作链中的最后一个过滤器。

Delta 过滤器与 LZMA2 一起使用可以对位图图像产生良好结果。它通常应胜过 PNG，PNG 有比简单 delta 更高级的几个过滤器，但使用 Deflate 进行实际压缩。

图像必须以未压缩格式保存，例如未压缩的 TIFF。Delta 过滤器的距离参数设置为匹配图像中每像素的字节数。例如，24 位 RGB 位图需要 `dist=3`，传递 `pb=0` 给 LZMA2 以适应三字节对齐也很好：

```sh
xz --delta=dist=3 --lzma2=pb=0 foo.tiff
```

如果多个图像已放入单个归档（例如 `.tar`），只要所有图像具有相同的每像素字节数，Delta 过滤器也将对其进行处理。

## 参见

[xzdec(1)](/man/man1/xzdec.1.md), xzdiff(1), xzgrep(1), xzless(1), xzmore(1), [gzip(1)](/man/man1/gzip.1.md), bzip2(1), 7z(1)

XZ Utils：<https://tukaani.org/xz/>

XZ Embedded：<https://tukaani.org/xz/embedded.html>

LZMA SDK：<https://7-zip.org/sdk.html>


---

# 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/man1/xz.1.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.
