OFFSET偏移
← 文章目录OFFSET / FIELD NOTESNO. 091

nh:统一 Nix 系统、用户和清理工作流

保留 nh 命令、模块选项、specialisation、搜索、环境变量和上游贡献说明。

所在专题Nix 命令与长期维护 ↗
约 29 分钟阅读开始阅读

来源与许可:本篇“nh 是什么?”、“功能特性”、“当前状态”、“使用方式”、“环境变量”、“常见问题”和“参与贡献”中的上游 README 译文与改编,来源于 nix-community/nh 项目及其贡献者。上述上游材料和对其所作的翻译、编排与修订按 EUPL-1.2(完整许可) 提供;不将该许可扩展至独立的模块配置参考、本站新增使用顺序说明或其他内容。许可核验依据为 上游 README 固定参考版本 25da175ed916 及其 LICENSE;此版本是本次核验的参考,不声称它就是最初导入的精确版本。本文包含翻译、选编和补充说明;2026-10-09 补充本许可及修改说明。本篇可编辑源码 保留译稿与改编内容;原文中的“我们”指上游项目,不表示上游认可本站。

nh 是什么?#

来源范围:本篇保存原笔记中的 nh 上游文档译稿与模块选项说明。原文包含开发分支功能(例如 SPAM 离线搜索及 GitHub PR/issue 搜索),不能保证发行版 stable 包全部具备;以安装版本 nh --version、各子命令 --help 和对应源码为准。

nh 是一个现代化的辅助工具,旨在统一和重新实现 Nix/NixOS 生态系统中多个工具的 命令与接口。我们的目标是提供一个一致的、易于理解的界面,具备 更多功能、更好的使用体验,以及更快的速度。除了作为一个集大成的一站式工具, 重新实现那些广为人知、高频使用的 Nix 命令之外,nh 还是一个_赏心悦目_的工具, 整合了你可能熟悉的相关第三方项目。

如需快速上手,可从“使用方式”和“命令示例”开始。

功能特性#

  • 统一 CLI:为 Nix、NixOS、Home Manager 和 Nix-Darwin 工作流提供一致、直观的交互界面。
  • 丰富的界面:每个主要功能(os、home、darwin、search、 clean)都提供了粒度精细的子命令和参数,方便精确控制。
  • 增强版垃圾回收:nh clean 扩展了 nix-collect-garbage, 支持 gcroots 清理、指定 profile、按时间保留。
  • 更快的 Nix 搜索:通过 Elasticsearch 搜索 Nixpkgs,响应速度更快。
  • 颜值在线:看起来赏心悦目,绝不妥协。谁不喜欢酷炫的界面呢?
    • 构建树可视化:nh os 等命令通过 nix-output-monitor(nom) 显示构建依赖树,一目了然。
    • 变更对比:在激活或切换前,集成超快的 derivation 变更差异展示。
  • Specialisation 支持:通过参数轻松选择或忽略 NixOS 和 Home-Manager 的 specialisation。
  • 世代管理:查看、回滚、管理系统世代,支持精确指定目标世代。
  • 可扩展且面向未来:旨在无缝、快速地增加新的子命令和参数。
    • nh 是对你所熟悉和喜爱的 CLI 工具的重新实现,但更注重 安全性和正确性。语言和设计上的选择使新功能的添加变得简单且几乎零开销。
  • 出色的文档:nh 能做的每一件事都有文档。nh 做了什么 也都有文档。 面向用户和开发者的文档永远保持最新。

设计理念

nh 是一个_统一的_ CLI,意味着它试图将核心平台支持整合到一个 方便的工具中。目前,nh 的界面体现为对 NixOS(一等公民)、Home Manager 和 Nix-Darwin 的支持。我们希望为这些项目的用户提供一个熟悉、方便 且_美观_的界面。

nh 的界面看似熟悉,但这不应被视为弱点——nh 不是一个 nixos-rebuild 的 包装器,也不受这类工具的限制。简而言之,我们的目标不仅是_实现已有功能_, 更要_超越既有能力_,实现额外的命令和参数来改进默认工具提供的体验。 也就是说,_基础设施_和_合理默认值_很重要。你可以享受你习惯的那些工具, 同时获得更快速、更安全语言带来的好处。

nh 的未来目标包括支持更底层的工具,如 nixos-install 和 nixos-generate-config,以成为大多数核心工具的 Rust 替代方案。 如果你想提供反馈和功能请求,欢迎到 Discussions 和 Issues 页面参与讨论。

当前状态#

下面关于发布与回移植的描述来自笔记快照;stable 实际包版本与回移植情况要按锁定 Nixpkgs 查询。

nh 已在 nixpkgs 中打包,同时提供 nixpkgs stable 和 nixpkgs unstable 版本。 原上游译稿描述其回移植政策,但不应把所有更新进入 stable 当作保证。详情见安装章节。 如果软件包过时,请务必提交 update request。

安装

最新的 tagged 版本在 Nixpkgs 中作为 nh stable 提供,推荐大多数用户使用, 因为 tagged 版本通常会经过更多测试。本仓库也提供 nh 的最新开发版本, 可以从 flake outputs 获取。

nix shell nixpkgs#nh             # 稳定版
nix shell github:nix-community/nh  # 开发版

无需任何配置,现在就能在 Nix shell 中试用 nh!

NixOS

我们提供 NixOS 模块,将 nh clean 作为系统服务运行。启用方式如下:

{
  programs.nh = {
    enable = true;
    clean.enable = true;
    clean.extraArgs = "--keep-since 4d --keep 3";
    flake = "/etc/nixos";  # NixOS 模块设置 NH_FLAKE
  };
}

programs.nh 模块配置参考#

nh(Nix Helper)是一个旨在简化 Nix 和 NixOS 命令行操作的工具。通过 programs.nh 模块,你可以以声明式的方式安装该工具、设置默认的 Flake 路径,并配置基于 nh 的系统自动清理任务。

选项列表

programs.nh.enable

  • 类型:布尔值 (Boolean)
  • 默认值:false
  • 描述:是否启用 nh 及其相关配置。设为 true 后,系统会将 nh 包安装到全局环境变量中。

programs.nh.package

  • 类型:Nix 包 (Package)
  • 默认值:pkgs.nh
  • 描述:指定要安装的 nh 软件包实例。通常保持默认即可,若需使用 特定版本或自定义编译的 nh,可在此处覆盖。

programs.nh.flake

  • 类型:空值或单行字符串 (null or string)
  • 默认值:null
  • 描述:指定 nh 默认操作的 Flake 路径。该值将被赋给环境变量 NH_FLAKE,用于诸如 nh os switch 等命令的默认 Flake 指向。
  • 覆盖机制:你可以通过设置以下环境变量来针对特定命令覆盖此默认值:
    • NH_OS_FLAKE:优先用于 nh os 命令。
    • NH_HOME_FLAKE:优先用于 nh home 命令。
    • NH_DARWIN_FLAKE:优先用于 nh darwin 命令。
  • 约束条件:该路径必须指向一个目录,不能是单独的 .nix 文件。 如果配置错误,系统构建时会抛出断言错误。

programs.nh.clean.enable

  • 类型:布尔值 (Boolean)
  • 默认值:false
  • 描述:是否启用基于 nh clean all 的定期垃圾回收机制。
  • 注意事项:如果启用了此项,必须禁用系统原生的 nix.gc.automatic = true,否则两者的定时任务会产生冲突, 并在构建时触发系统警告。

programs.nh.clean.dates

  • 类型:单行字符串 (singleLineStr)
  • 默认值:"weekly"
  • 描述:定义清理任务的执行频率。该字符串将传递给 systemd.time。
  • 格式参考:支持 systemd.time(7) 中定义的时间格式,例如 "weekly"、"daily" 或具体时间 "03:30"。

programs.nh.clean.extraArgs

  • 类型:单行字符串 (singleLineStr)
  • 默认值:""
  • 描述:在自动清理服务运行时,附加传递给 nh clean all 命令的 额外参数。
  • 示例:"--keep 5 --keep-since 3d"(保留最近 5 个世代,且保留 3 天内的所有世代)。具体可用参数请参考 nh clean all --help。

配置示例

以下是一个在 configuration.nix 中启用并配置 nh 的标准示例:

{ config, lib, pkgs, ... }:
{
  # 启用 nh 工具
  programs.nh = {
    enable = true;

    # 指定默认的 Flake 路径,简化日常命令
    flake = "/etc/nixos";

    # 配置 nh 接管系统的自动垃圾回收
    clean = {
      enable = true;
      dates = "weekly";  # 每周执行一次

      # 保留策略:至少保留最近 5 个世代,且近 7 天内的世代全部保留
      extraArgs = "--keep 5 --keep-since 7d";
    };
  };

  # 关键:禁用原生 nix.gc 以避免与 nh 的清理任务冲突
  nix.gc.automatic = lib.mkForce false;
}

从 4.0 版本开始,nh 完全支持 Nix flakes 和通过 channels 或手动依赖 管理的传统 NixOS 配置。请将新的 API 视为成熟但略显实验性的功能。 欢迎报告任何 bug!

  • 对于 flakes,命令为 nh os switch /path/to/flake
  • 对于传统配置:
    • nh os switch -f '<nixpkgs/nixos>',或
    • nh os switch -f '<nixpkgs/nixos>' -- -I nixos-config=/path/to/configuration.nix(如果你使用非默认路径)

你可以查看 nh os --help 或 man 1 nh 获取其他参数和环境变量的默认值。

Specialisation 支持

nh 能够检测你当前正在运行哪个 specialisation,并执行正确的激活脚本。 为此,你需要通过将 specialisation 的名称写入 /etc/specialisation 来告知 nh:

{config, pkgs, ...}: {
  specialisation."foo".configuration = {
    environment.etc."specialisation".text = "foo";
    # ..其余配置
  };

  specialisation."bar".configuration = {
    environment.etc."specialisation".text = "bar";
    # ..其余配置
  };
}

Home-Manager

Home specialisation 通过 ~/.local/share/home-manager/specialisation 读取。 配置如下:

{config, pkgs, ...}: {
  specialisation."foo".configuration = {
    xdg.dataFile."home-manager/specialisation".text = "foo";
    # ..其余配置
  };

  specialisation."bar".configuration = {
    xdg.dataFile."home-manager/specialisation".text = "bar";
    # ..其余配置
  };
}

使用方式#

nh 的核心原则之一是为用户提供清晰、统一、直观的 CLI 体验。nh 命令 提供了多个子命令,均包含丰富的 CLI 参数,支持灵活的配置。

nh 支持各种参数、环境变量和配置选项,以提供最佳用户体验。 可以查看各个子命令的 --help 页面,或 man 1 nh 获取更详细的信息 和示例。你也可以使用相关平台的模块(如 Nixpkgs 中的 NixOS 模块) 来为你的系统进行定制,如安装章节所述。

在 nh 命令下,有两类你会用到的命令:

全局子命令

全局子命令围绕核心 Nix 命令提供增强功能。目前,我们提供了更好的搜索 和更好的垃圾回收体验,通过两个开箱即用的子命令实现。

nh search

我们提供了超快的 Nix 包和 NixOS/Home Manager 选项搜索工具(基于 search.nixos.org 的 Elasticsearch 后端),支持本地 SPAM 数据库的离线搜索,以及 Nixpkgs pull request 和 issue 搜索。全部通过 nh search 使用!这些扩展搜索子命令属于笔记记录的功能快照;若发行版 nh search --help 未显示它们,就不要套用。

笔记列出了以下搜索模式和便捷简写形式:

调用方式 功能说明
nh search <query> 简写形式;默认搜索包(可通过 NH_DEFAULT_SEARCH 修改默认行为)
nh search packages <query> 通过 search.nixos.org 搜索 Nixpkgs 包
nh search options [--scope=<SCOPE>] <query> 搜索 NixOS/Home Manager 选项(--scope: nixpkgs、home-manager、all)
nh search offline --db <PATH> <query> 离线搜索本地 SPAM 数据库。预生成的数据库需从上游 SPAM 项目找到与本机匹配的版本。
nh search prs [--days <DAYS>] <query> 搜索 Nixpkgs pull request 并显示已合入 PR 的分支可达性。默认 15 天内。
nh search issues [--days <DAYS>] <query> 搜索 Nixpkgs issue,不含 pull request。默认 15 天内。

--json 对所有搜索模式通用。--limit、--channel 和 --platforms 在适用这些参数的搜索模式和简写形式中均可用。

nh search prs 和 nh search issues 使用 GH_TOKEN 进行 GitHub 认证。 如果 GH_TOKEN 未设置,nh 会从 NH_GITHUB_TOKEN_FILE 读取 token, 或者从 $XDG_STATE_HOME/nh/github-token(回退到 ~/.local/state/nh/github-token)读取。如果在交互式终端中未找到 token, nh 会提示你输入并将其保存到 token 文件中。

nh clean

对 nix-collect-garbage 的重新实现,同时清理 gcroots,提供各种选项来精细 控制保留哪些内容,并在清理之前展示额外信息,让你了解哪些内容将被清理。

原文版本中,nh clean 的 gcroots 清理会检查你的 gcroots 目录;移除相应根会使构建结果或 direnv 缓存不再受保护,而非保证删除所有项目目录。默认开关和清理范围须用本机 nh clean --help 核对。

使用 --no-gcroots 跳过所有 gcroot 清理,或使用 --no-direnv 保留 direnv gcroots 的同时清理其他所有内容。

平台专属子命令

平台专属子命令为 NixOS、Home Manager 和 Nix-Darwin 实现 CLI 工具。

nh os

nh os 子命令从零开始重新实现了 Python 脚本 nixos-rebuild-ng[^1], 并额外增加了:

  • 通过 nix-output-monitor(nom)展示构建树
  • 通过 dix 展示漂亮的变更差异
  • 确认提示

以及其他界面改进,从支持环境变量到额外的安全保护措施。就这些吗?不, 还有更多值得期待。

nh home

nh home 子命令重新实现了 home-manager 脚本,并增加与 nh os 相同的增强功能。

nh darwin

最后但同样重要的是,nh darwin 子命令是对 darwin-rebuild 脚本的 纯 Rust 重新实现,具备与 nh os 和 nh home 相同的增强功能。

命令示例

平台 旧命令(无 nh) 新命令(使用 nh)
NixOS nixos-rebuild switch --flake .#workstation nh os switch . -H workstation
Darwin darwin-rebuild switch --flake .#workstation nh darwin switch . -H workstation
Home Manager home-manager switch --flake .#workstation nh home switch . -c user

如果 NH_FLAKE 变量已设置,nh 允许省略 flake 路径。在 NixOS 和 Home-Manager 模块中,如果 programs.nh.flake 已设置,此操作会自动完成。

nh 还允许在系统能够自动发现时省略 NixOS/Darwin 的主机名(-H)和 Home Manager 的配置名(-c)参数。例如,如果 NH_OS_FLAKE 已设置, 你可以直接运行 nh os switch,无需额外参数,它会自动解析 nixosConfigurations.<workstation>。

此外,nh 也允许省略非 flake 配置的 Nix 文件路径。你可以通过 NH_FILE 和 NH_ATTRP 环境变量指定 Nix 文件和 Nix 属性路径。如果 NH_FILE 和 NH_ATTRP 都已设置,nh os switch 实际执行的是 $NH_FILE#$NH_ATTRP。

环境变量#

部分变量来自开发分支文档;支持程度需要按 installed nh 版本核对。变量名本身不是凭据,此处不含任何 token 值。

nh 支持多种环境变量来控制命令行为。以下是你可能遇到或选择使用的常见变量:

全局

  • NIX_SSHOPTS、NIX_CONFIG 和 NIX_REMOTE 在带环境隔离的所有 Nix 命令中都会被转发。
  • NIX_SSL_CERT_FILE
    • 为 Nix 指定 TLS CA 证书文件,与引导器安装没有关系。
  • NIX_USER_CONF_FILES
    • 指定客户端读取的 Nix 配置文件列表。
  • NIXOS_INSTALL_BOOTLOADER
    • 系统激活时与重新安装引导器相关;不要把它误当 TLS 配置。其具体取值和激活脚本行为要按系统版本核对。

NH 专属

  • NH_NO_CHECKS

    • 当设置为非空值时,跳过启动检查(如 Nix 版本和实验性功能验证)。 适用于生成补全或运行受限构建环境。你也可以将其视为"专家模式", 设置后可获得少量性能提升。前提是你知道自己在做什么。
  • NH_FLAKE

    • 运行基于 flake 的命令时,NH 使用的包含 flake.nix 的目录的 首选路径/引用。历史上前身是 FLAKE;如果在特定平台的 NH_*_FLAKE 未设置时 FLAKE 存在,NH 会将其迁移到 NH_FLAKE。
  • NH_OS_FLAKE、NH_HOME_FLAKE、NH_DARWIN_FLAKE

    • 分别为 os、home 和 darwin 命令指定的 flake 引用。 如果存在,优先级高于 NH_FLAKE。
  • NH_SUDO_ASKPASS

    • NH 使用 sudo 提权时调用的辅助程序路径。如果设置了 SUDO_ASKPASS,NH 将传递 -A 给 sudo。
  • NH_PRESERVE_ENV

    • 控制是否将标记为保留的环境变量传递给提权后的命令。 设置为 "0" 禁用保留,"1" 强制保留。如果未设置,保留默认启用。
  • NH_SHOW_ACTIVATION_LOGS

    • 控制是否显示激活输出。默认情况下,激活输出是隐藏的。 设置为 "1" 将显示完整的激活日志,便于调试激活失败。 所有平台(NixOS、Home Manager 和 Darwin)均支持。
  • NH_LOG

    • 设置 NH 的日志/追踪过滤器。使用与 tracing_subscriber 环境过滤器相同的格式(例如:nh=trace)。
  • NH_CONFIG

    • 覆盖 NH 配置文件的路径。如果未设置,NH 使用 $XDG_CONFIG_HOME/nh/config.toml,回退到 ~/.config/nh/config.toml。
  • GH_TOKEN

    • nh search prs 和 nh search issues 使用的 GitHub token。 如果设置,优先级高于任何 token 文件。
  • NH_GITHUB_TOKEN_FILE

    • 覆盖 nh search prs 和 nh search issues 在 GH_TOKEN 未设置时使用的 GitHub token 文件路径。如果未设置,NH 使用 $XDG_STATE_HOME/nh/github-token,回退到 ~/.local/state/nh/github-token。通过交互式提示输入的 token 会以仅用户可读的权限保存到此文件。
  • NH_SEARCH_CHANNEL

    • nh search packages 和 nh search options 使用的默认 Nixpkgs channel(如 nixos-unstable)。可通过 --channel 参数 逐次覆盖。
  • NH_SEARCH_JSON

    • 设置为真值时,nh search 以原始 JSON 格式输出结果,而非格式化 显示。等价于 --json。
  • NH_SEARCH_PLATFORM

    • 设置为真值时,每个包结果会显示支持的平台。等价于 --platforms。
  • NH_DEFAULT_SEARCH

    • 控制 nh search <query> 简写形式的目标(不指定子命令时)。 可接受的值为:packages(默认)、options、all。等价于 --default-search。
  • NH_OFFLINE_DB

    • 冒号分隔的 SPAM 数据库文件路径列表,供 nh search offline 使用。 每个路径会被视为独立的数据库。等价于多次传递 --db。 示例:NH_OFFLINE_DB=/var/cache/spam/nixpkgs.db:/var/cache/spam/hm.db。
  • NH_NOM

    • 控制是否在构建过程中启用 nom(nix-output-monitor)。 等价于 --no-nom。
  • NH_REMOTE_CLEANUP

    • 是否在中断时尝试通过 pkill 清理远程进程。此功能为匹配 nixos-rebuild 的行为而实现,但由于其脆弱的本质,默认关闭。 除非 NH 在中断后留下了僵尸进程,否则通常无需设置。

注意事项

  • 以 NH_ 为前缀的任何环境变量,在适当时(即在环境隔离中)都会由 NH 显式传播给子命令。
  • 为了向后兼容,如果 FLAKE 存在且没有设置任何平台专属的 NH_*_FLAKE 变量,NH 会将 NH_FLAKE 设为 FLAKE 的值,并输出警告建议迁移。 FLAKE 将在未来版本的 NH 中移除。

常见问题(FAQ)#

Q:nh 是否封装了我平时使用的 CLI 工具?

A:不,所有命令都直接调用 Nix,它们不消费传统的 CLI 工具。nh 正在逐步将原本通过 shell 调用的工具转换为原生 Rust 库,以获得更安全的 集成和略好的性能。

参与贡献#

欢迎贡献。只需克隆仓库并运行 nix develop。我们也为 Direnv 用户 提供了 .envrc,使用 direnv allow 即可进入开发环境。

[^1]:nixos-rebuild-ng 尚未提供与 nixos-rebuild 完全的功能对等。 虽然大量子命令已实现,但你可能仍缺少某些功能。详情请访问 #358 查看路线图。

结构

以下 src/xtask 说明保留旧译稿的代码布局;当前仓库可能已拆成 crates、docs 等目录,贡献时先查看当前 CONTRIBUTING 文档。

nh 使用 Rust 编写,由两个模块组成。核心代码位于 src 目录,并分离到 不同的子模块中。你需要关注的关键模块包括:nh::commands 负责命令 接口,nh::checks 负责启动前检查,nh::util 存储共享逻辑。 平台相关的逻辑放在对应的平台模块中,如 nh::nixos 或 nh::darwin, 通用辅助函数放在 nh::util 中。

xtask 目录包含 NH 使用的 cargo-xtask 任务,用于生成 manpage 等。

提交变更

完成修改后,请记得运行 just fix 来应用 CI 期望的通用格式化和 lint 规则。

你还需要在创建变更前用足够的信息更新 changelog 来描述新行为。

这看起来可能让人望而却步,其实不然。即使你_没有_达到这些要求,也会被温和地 引导完成修改。友好的贡献总是受欢迎的。

致敬

nh 拥有很长的历史,多年来已成长了很多。原译稿以 NotAShelf 的口吻介绍项目历史,首先感谢 ViperML,作为 nh 的创建者和第一任维护者,付出了巨大的努力。 我最近接管了 nh,但没有他,这一切都不可能实现。

接下来,我要感谢我们底层使用的工具。升级差异可视化由我的好朋友 faukah 创建的 dix crate 提供。与之前的差异工具 nvd 相比,dix 速度超过两倍, 对 nh 的差异体验来说是一个福音。谢谢你!

nix-output-monitor 也是一个值得一提的优秀工具,nh 在底层使用它来展示 漂亮的构建树。非常感谢 nix-output-monitor 为无数像我这样的 nh 用户提供 精美的构建可视化。

我也要感谢驱动 nh 底层、赋予其标志性 UX 的众多 Rust crates。 没有美丽的 Rust 生态系统,nh 无法走到今天。

最后但同样重要的是,我要感谢……你!感谢每一位为 nh 做出贡献、讨论 nh、 批评 nh 以推动改进的人。没有你们,就没有 nh 的今天。

构建、激活与清理的使用顺序#

系统命令可先选择 nh os build 检查构建结果;nh os test 仍会实际激活服务,nh os switch 修改运行系统与默认配置。nh clean 会削减可恢复世代与缓存,在确认保留时间、世代数及 gcroots 范围后使用。NixOS 的 programs.nh.flake 设置 NH_FLAKE,平台专属的 NH_OS_FLAKE 等优先级更高;不要把两者混写。上游源码模块确认 clean 与原生 nix.gc 自动任务同时启用会发出警告;选择一个定时器即可。

参考与延伸

  1. nh 上游项目 ↗
  2. NixOS nh 模块源码 ↗
  3. SPAM 项目 ↗
  4. nh README:本次许可核验的固定参考版本 ↗
  5. nh:该参考版本的 EUPL-1.2 许可 ↗
  6. 完整 EUPL-1.2 许可 ↗
  7. 本篇可编辑源码 ↗

根据技术笔记重新整理,示例使用通用名称。

沿专题继续阅读

Nix 命令与长期维护

  1. 01NixOS 学习路线:基础、Flakes、用户配置与进阶
  2. 02Nix 命令详解:构建、环境、profile 与系统
  3. 03nh:统一 Nix 系统、用户和清理工作流
  4. 04垃圾回收、存储优化与回滚世代
  5. 05NixOS 配置组织、维护与排错实践
CONTINUE READING / 下一篇NixOS 学习路线:基础、Flakes、用户配置与进阶

保存六个学习模块、语言生态和进阶资源,并给出清晰的前后依赖。