为何`sudo nixos-rebuild`不显示trace输出?配置内容未打印问题
lib.debug.showVal在nixos-rebuild dry-build中没输出config内容? 这个问题其实和Nix的评估阶段、dry-build的行为,以及lib.debug.showVal的工作方式都有关系,我来拆解一下:
核心原因
lib.debug.showVal的输出逻辑:showVal的作用是把传入的值转换成人类可读的字符串,但它本身是返回这个值,而非主动打印输出。只有当这个被showVal包装后的值被Nix的构建过程实际“调用”时,对应的字符串才会被写入构建日志——但dry-build模式并不会执行实际构建步骤,它只停留在配置评估和依赖解析阶段,所以不会触发这个日志输出。dry-build的行为限制:nixos-rebuild dry-build的核心目的是展示“如果执行build会构建哪些派生包”,它会跳过构建阶段的所有日志输出,包括showVal产生的内容。哪怕你加了--show-trace,这个参数也只是展示评估过程中的错误追踪,不会包含showVal的调试输出。
解决办法
方法1:改用lib.debug.traceVal(推荐)
lib.debug.traceVal是专门用来在配置评估阶段直接打印值的工具,它会把值输出到标准错误流,不管是不是dry-build模式。修改你的代码:
let config_ = lib.debug.traceVal config; in { # 你的其他配置 systemd = import ./systemd { inherit pkgs; config = config_; }; }
执行nixos-rebuild dry-build --show-trace时,你就能在终端看到config的完整内容了。
方法2:手动用lib.debug.trace定制输出
如果需要更易读的格式,可以用lib.debug.trace配合lib.generators.toPretty来格式化输出:
let config_ = config; # 把config格式化为JSON风格的可读字符串 configStr = lib.generators.toPretty {} config_; in lib.debug.trace "=== 当前Config内容 ===" ( lib.debug.trace configStr { systemd = import ./systemd { inherit pkgs; config = config_; }; # 你的其他配置项 } )
这种方式会在评估时直接把格式化后的config内容打印到终端,非常直观。
方法3:强制触发构建日志输出
如果你一定要用lib.debug.showVal,可以放弃dry-build,改用build模式并开启详细日志:
sudo nixos-rebuild build --show-trace -v
这样构建过程中会输出showVal生成的字符串,但缺点是会实际构建系统配置,耗时更长。
内容的提问来源于stack exchange,提问作者srghma

