咨询Nix中modulesPath的含义及Nix常量值的获取方法
modulesPath的含义及获取Nix常量值的方法 问题背景
我的/etc/nixos/configuration.nix中有如下配置代码:
{ lib, pkgs, config, modulesPath, ... }: with lib; let nixos-wsl = import ./nixos-wsl; in { imports = [ "${modulesPath}/profiles/minimal.nix" nixos-wsl.nixosModules.wsl ]; }
我想了解${modulesPath}的具体含义,尝试了以下操作但未得到预期结果:
在shell中执行:
echo ${modulesPath}无任何输出。
在
nix repl中输入${modulesPath},得到报错:error: syntax error, unexpected DOLLAR_CURLY
modulePatherror: undefined variable 'modulesPath'
无任何有效输出。
更新尝试
后来我在nix repl中输入{modulesPath}: modulesPath,得到结果:
«lambda @ (string):1:1»
结果显示它是一个lambda,但我原本以为会得到一个字符串值。
请问modulesPath到底是什么?更普遍地说,如何获取这类“Nix常量”的值?
解答
1. modulesPath的本质
modulesPath是NixOS模块系统在解析配置时自动注入的参数,它是一个字符串,指向当前使用的NixOS版本对应的官方模块集合的根目录。比如你配置里的"${modulesPath}/profiles/minimal.nix",就是引用官方提供的最小化系统配置模块。
它不是全局变量,而是配置文件(本质是一个函数)的参数——你代码第一行{ lib, pkgs, config, modulesPath, ... }:就定义了这个函数的参数列表,这些参数由NixOS构建系统自动传入,因此无法直接在shell或无上下文的nix repl中访问。
2. 正确获取modulesPath的值
方法一:通过nix-instantiate命令直接求值
在终端执行以下命令,加载NixOS上下文并输出modulesPath的实际路径:
nix-instantiate --eval -E 'with import <nixpkgs/nixos> {}; modulesPath'
执行后会输出类似"/nix/store/xxxxxx-nixos-23.11/share/nixos/modules"的路径,这就是官方模块的存放位置。
方法二:在nix repl中正确获取
之前的写法只是定义了一个接收modulesPath参数的lambda,但未传入实际值。正确做法是先导入NixOS模块上下文,再访问该参数:
nix repl
然后输入:
(import <nixpkgs/nixos> {}).modulesPath
即可得到实际的路径字符串。
3. 获取Nix“常量”的通用方法
大部分NixOS配置中的“常量”(如lib、pkgs、modulesPath)要么是配置函数的参数,要么是Nixpkgs/NixOS模块导出的值,获取它们的通用思路:
- 明确来源:如果是配置函数参数,需通过
import <nixpkgs/nixos>获取NixOS上下文;如果是lib工具函数,通过import <nixpkgs>导入Nixpkgs上下文。 - 使用
nix-instantiate --eval直接求值,比如获取Nixpkgs版本:nix-instantiate --eval -E '(import <nixpkgs> {}).lib.version' - 在
nix repl中先导入上下文再访问:nix repl :l <nixpkgs> lib.version
内容的提问来源于stack exchange,提问作者Pierre-olivier Gendraud

