Chapter 02

Nix 包管理器基础

掌握 nix 命令族——搜索、临时使用、安装包,以及如何管理 Nixpkgs 频道和清理垃圾

两套命令体系

Nix 有新旧两套命令,理解它们的关系很重要:

新命令(推荐)
nix searchnix shellnix runnix buildnix profile 等。需要启用 nix-command 实验特性(Determinate Installer 默认启用)。与 Flakes 深度集成,支持 nixpkgs#package 语法。
经典命令(兼容)
nix-envnix-shellnix-buildnix-channel 等。无需特殊配置即可使用,但功能相对受限,不支持 Flakes。旧教程和配置文件中常见,仍需了解。

搜索包:nix search

# 在 nixpkgs 中搜索包(模糊匹配名称/描述)
nix search nixpkgs#ripgrep
nix search nixpkgs nodejs     # 也可省略 # 前缀

# 搜索结果示例:
# * legacyPackages.x86_64-linux.nodejs (20.11.0)
#   Event-driven I/O framework for the V8 JavaScript engine
# * legacyPackages.x86_64-linux.nodejs_18 (18.19.0)
#   Event-driven I/O framework for the V8 JavaScript engine

# 用 JSON 格式输出(便于脚本处理)
nix search nixpkgs#python3 --json | jq '.[].description'

# 经典方式:nix-env 搜索(需要先同步频道)
nix-env -qaP python3    # -q 查询,-a 所有可用,-P 显示属性路径
在线搜索更方便

访问 search.nixos.org 可以在线搜索 Nixpkgs 中的所有包,支持按稳定版/unstable 筛选,显示包的完整属性路径,比命令行更直观。

临时使用包:nix shell

nix shell 是 Nix 最实用的功能之一:进入一个临时 Shell,其中包含你指定的包,退出后系统环境完全干净,不会污染全局

# 进入含有 ripgrep 的临时 shell
nix shell nixpkgs#ripgrep
rg --version           # 在此 shell 中可用
exit                   # 退出后 rg 不再可用

# 同时引入多个包
nix shell nixpkgs#nodejs nixpkgs#yarn nixpkgs#git
node --version         # Node.js 可用
yarn --version         # Yarn 可用

# 指定特定版本(使用属性路径)
nix shell nixpkgs#nodejs_18
nix shell nixpkgs#python311

# 使用 nixpkgs-unstable(最新包)
nix shell nixpkgs/nixpkgs-unstable#neovim

# 使用特定 nixpkgs commit(极致可复现)
nix shell github:NixOS/nixpkgs/abc123def456#hello

直接运行包:nix run

nix run 更进一步:下载并直接运行一个包,无需先进入 shell,用完即走:

# 直接运行 cowsay
nix run nixpkgs#cowsay -- "Hello, Nix!"

# 运行 Python 解释器
nix run nixpkgs#python3 -- --version

# 运行自定义 flake 中定义的应用
nix run github:some-user/some-project

# 实用场景:临时使用不想常驻的工具
nix run nixpkgs#ffmpeg -- -i input.mp4 output.gif
nix run nixpkgs#imagemagick -- convert photo.png photo.webp
nix run nixpkgs#yt-dlp -- https://example.com/video

用户级包安装:nix profile

如果你确实需要将包"安装"到用户环境中持久可用,使用 nix profile(新命令):

# 安装包到用户 profile
nix profile install nixpkgs#bat    # 安装 bat(更好的 cat)
nix profile install nixpkgs#fd     # 安装 fd(更好的 find)

# 列出已安装的包
nix profile list
# 输出示例:
# 0  flake:nixpkgs#legacyPackages.x86_64-linux.bat
# 1  flake:nixpkgs#legacyPackages.x86_64-linux.fd

# 卸载包(用 --profile 中的序号)
nix profile remove 1    # 卸载序号为 1 的包

# 升级所有已安装包
nix profile upgrade '.*'

# 回滚到上一个 profile generation
nix profile rollback

经典命令:nix-env

了解 nix-env 有助于阅读旧文档和配置,但新项目推荐用 nix profile

# 安装包(从当前频道)
nix-env -iA nixpkgs.bat       # -i 安装,-A 按属性路径
nix-env -iA nixpkgs.ripgrep

# 列出已安装包
nix-env -q                    # -q 查询已安装

# 卸载包
nix-env -e bat                # -e erase(卸载)

# 升级所有包
nix-env -u                    # -u upgrade

# 回滚到上一 generation
nix-env --rollback

# 查看所有 generation
nix-env --list-generations
# 输出示例:
#    1   2024-01-15 10:32:00   (current)

# 切换到指定 generation
nix-env --switch-generation 2

Nixpkgs 频道管理

Nixpkgs 有多个"频道"(channel),对应不同的稳定程度:

nixos-24.05(稳定版)
NixOS 2024 年 5 月发布的稳定版,每 6 个月发布一次(5 月和 11 月)。适合生产环境,包版本固定,安全补丁会 backport。
nixpkgs-unstable
跟踪 nixpkgs 主分支,包含最新版本,每天多次更新。适合需要最新软件的开发者,但偶尔可能有构建失败。
nixos-unstable
类似 nixpkgs-unstable,但同时包含 NixOS 模块的最新改动,NixOS 用户可用此频道获取最新系统特性。
# 查看当前频道
nix-channel --list
# 输出示例:
# nixpkgs https://nixos.org/channels/nixpkgs-unstable

# 添加/更改频道
nix-channel --add https://nixos.org/channels/nixpkgs-unstable nixpkgs
nix-channel --add https://nixos.org/channels/nixos-24.05 nixpkgs-stable

# 更新频道(下载最新包元数据)
nix-channel --update

# 删除频道
nix-channel --remove nixpkgs-stable
Flakes 取代频道

如果你使用 Flakes(第7章),不需要管理频道——flake.nix 直接引用 GitHub 上的 nixpkgs,flake.lock 精确锁定 commit,比频道更可靠。

垃圾回收:释放磁盘空间

Nix store 会持续积累旧版本的包,需要定期清理。

# 查看 nix store 占用空间
du -sh /nix/store
nix store info           # 显示 store 路径和版本

# 删除所有旧 generation(仅保留当前 generation)
nix-collect-garbage -d   # -d / --delete-old 删除旧代

# 仅删除 7 天前的旧 generation
nix-collect-garbage --delete-older-than 7d

# 先删除旧 generation,再运行 GC
nix-env --delete-generations old    # 删除除当前外的所有 generation
nix-store --gc                      # 运行垃圾回收

# NixOS 系统级 GC(需要 root)
sudo nix-collect-garbage -d         # 同时清理系统 profile 的旧代
sudo nix-store --optimise           # 硬链接去重,进一步节省空间

# 查看 GC roots(哪些路径阻止了 GC)
nix-store --gc --print-roots | grep -v '/proc'

自动 GC 配置

# 在 NixOS configuration.nix 中配置自动 GC
{
  nix.gc = {
    automatic = true;
    dates = "weekly";           # 每周运行一次
    options = "--delete-older-than 14d";  # 删除 14 天前的旧代
  };

  # 自动硬链接去重(节省磁盘)
  nix.settings.auto-optimise-store = true;
}
GC 前确认

执行 nix-collect-garbage -d 会删除所有旧 generation,之后就无法直接回滚了(NixOS 的引导菜单也会少几项)。如果你觉得当前系统配置可能需要回退,可以先只删除很旧的代:nix-collect-garbage --delete-older-than 30d

本章小结

Nix 的日常包管理工作流:搜索用 nix search nixpkgs#name,临时使用用 nix shell(推荐,不污染系统),永久安装用 nix profile install,定期用 nix-collect-garbage -d 清理空间。理解新旧命令的对应关系,能帮助你读懂各种文档和配置文件。