背景说明:Nix 的命令行经历了历史包袱的折磨,导致
nix-xxx(旧版独立命令)和nix xxx(新版统一子命令)并存。开启nix-command和flakes后可使用新 CLI,但旧命令仍用于旧 profile、channels 和特定管理操作。新 CLI 仍有实验性接口,按安装版本查阅帮助。
一、 日常生存包(只需记住这 4 个)#
作为日常使用者,先理解以下四类操作及其影响:
| 场景 | 命令 | 说明 |
|---|---|---|
| 应用配置更改 | sudo nixos-rebuild switch |
改完 configuration.nix 或 flake.nix 后执行。若用 Flakes,通常为 sudo nixos-rebuild switch --flake .#主机名 |
| 更新系统所有软件 | sudo nixos-rebuild switch --upgrade |
channels 配置更新 channel 后构建并激活;Flake 工作流先更新 lock。 |
| 系统弄坏了,后悔药 | sudo nixos-rebuild switch --rollback |
立即回滚到上一个 Generation(无需重启,但建议重启确认)。 |
| 硬盘满了,清理垃圾 | sudo nix-collect-garbage -d |
删除所有旧世代并回收 /nix/store 空间。执行后无法回滚到已被删除的世代。 |
二、 新旧 CLI 替代关系对照#
开启 experimental-features = [ "nix-command" "flakes" ] 后,新版子命令提供对应功能;profile 格式和依赖来源不同,不能把表中命令视为无条件等价替换。
| 旧 CLI | 新 CLI | 用途 |
|---|---|---|
nix-env -iA nixpkgs.hello |
nix profile add nixpkgs#hello |
用户级软件安装 |
nix-env -e hello |
nix profile remove hello |
用户级软件卸载 |
nix-env --list-generations |
nix profile history |
查看历史世代 |
nix-build |
nix build |
构建 Derivation |
nix-shell -p python3 |
nix shell nixpkgs#python3 |
进入临时依赖环境 |
nix-channel --update |
nix flake update |
分别更新 channel 或 Flake 锁定输入(并非同一数据源) |
nix-instantiate --eval |
nix eval |
求值 Nix 表达式 |
** 注意例外**:
nixos-rebuild(系统管理)和nix-collect-garbage(垃圾回收)负责系统重建及 profile 历史配合 GC;nix-collect-garbage也能在非 NixOS 系统使用,nix store gc仅处理未被引用的 store 对象。
三、 常用新版命令(开发与测试)#
- 临时运行程序(不安装):
nix run nixpkgs#cowsay -- "Hello NixOS" - 进入临时 Shell 环境:
nix shell nixpkgs#python3 nixpkgs#postgresql - 进入项目开发环境(需项目根目录有
flake.nix配置devShells):nix develop
四、 Generation(世代)管理进阶#
Generation 就像游戏的"存档"。会更新系统 profile 的 switch/boot 可记录新存档,单独 build/dry-build 不会,旧的不会自动删除。
| 操作 | 命令 |
|---|---|
| 列出所有系统世代 | sudo nixos-rebuild list-generations |
| 切换到指定世代 (如第 50 号) | sudo nix-env --profile /nix/var/nix/profiles/system --switch-generation 50,随后运行该 profile 的 bin/switch-to-configuration switch 激活 |
| 删除指定世代 | sudo nix-env --profile /nix/var/nix/profiles/system --delete-generations 50 51 |
| 只保留最近 5 个世代 | sudo nix-env --profile /nix/var/nix/profiles/system --delete-generations +5 |
| 保留近 30 天的世代 | sudo nix-collect-garbage --delete-older-than 30d (推荐,比 -d 更安全) |
| 开机时通过 GRUB 回滚 | 重启后在 GRUB 菜单选择 "NixOS - All configurations" |
store GC 与删除 profile 历史
新版的 nix CLI 虽然有 nix store gc(用于清理底层 store 目录),但它不会自动帮你删除旧的 generations(世代)。如果你只用 nix store gc,那些旧世代还在,对应的包就不会被判定为"未引用",也就清不掉。nix-collect-garbage 默认仅回收不可达对象;加 -d 或 --delete-older-than 才会先删除它找到的 profiles 的旧历史。以 root 执行可能影响多个用户的 profiles,必须了解其扫描范围。
系统 profile 的历史接口
新版 nix profile 为新 profile 工作流提供接口;在处理 NixOS 系统级配置(路径在 /nix/var/nix/profiles/system)时,新旧命令的差异如下:
- 如果你想用新命令清理(可以替代):
你可以用nix profile wipe-history来替代nix-env。
# 新命令:删除 30 天前的非当前历史(先确认本机版本支持此 profile)
sudo nix profile wipe-history --profile /nix/var/nix/profiles/system --older-than 30d- 为何保留传统历史接口和 GC 工具:
按时间或按数量保留是维护策略选择。而nix-collect-garbage --delete-older-than 30d把"删世代"和"清空间"一步到位完成了。如果用新命令,需要分两步走(先用nix profile wipe-history删世代,再用nix store gc清空间),便于分别控制历史删除范围和空间回收。
五、 声明式自动维护(写进配置文件)#
为了避免手动敲清理命令,可以直接在 configuration.nix 中开启自动维护:
{ config, pkgs, ... }:
{
# 1. 限制 GRUB 启动菜单中保留的世代数量(避免启动列表过长)
boot.loader.grub.configurationLimit = 20;
# 2. 开启新版命令与 Flakes
nix.settings.experimental-features = [ "nix-command" "flakes" ];
# 3. 自动垃圾回收(每周清理 30 天前的世代)
nix.gc = {
automatic = true;
dates = "weekly";
options = "--delete-older-than 30d";
};
# 4. 自动优化存储(硬链接去重,节省空间)
nix.settings.auto-optimise-store = true;
# 5. (可选) 构建期间尝试 GC 的可用空间阈值,不是容量硬限制
nix.extraOptions = ''
min-free = ${toString (5 * 1024 * 1024 * 1024)}
max-free = ${toString (10 * 1024 * 1024 * 1024)}
'';
}六、按职责记忆命令#
- 日常系统管理:
nixos-rebuild;临时程序和开发环境:nix run、nix shell、nix develop。 - profile、channels 与旧表达式维护:
nix-env、nix-build、nix-shell、nix-channel仍有适用场景,是否采用取决于工作流。 - 安装和救援:
nixos-install、nixos-enter、nixos-generate-config,安装后仍可能用于恢复。
稳定的系统和用户环境适合用配置文件管理;临时探索可以用命令式环境。垃圾回收不会自动删除所有已安装软件,也不会保留已经移除的回滚点。
命令表按当前 Nix 2.34 接口给出,nix profile install 是 add 的兼容别名;较旧版本可能只有旧名称。只有包输出进入 store 不等于永久安装,临时环境结束后输出也可能留在 store,之后由 GC 回收。
参考与延伸
根据技术笔记重新整理,示例使用通用名称。