nix-env:了解活动 Nix 表达式中的可用属性路径
nix-env: understading available attribute paths in the active Nix expression
在我的 NixOS 机器上,我可以使用 nix-env
以两种方式查询 ghc
包:
一个是 nix-env -f '<nixpkgs>' -qaP ghc
,它导致输出
ghc ghc-8.6.5
另一个是 nix-env -qaP ghc
,它导致输出
nixpkgs.ghc ghc-8.6.5
对于第二种情况,我想理解为什么活跃的Nix表达式有一个nixpkgs
根属性。
~/.nix-defexpr
文件夹和几个子文件夹的内容如下:
如何从~/.nix-defexpr
的内容中组装出活跃的Nix表达式?为什么没有 channels
根属性? nixpkgs
根属性的名称是源自 nixpkgs
文件夹的名称,还是源自文件夹的内容,或许源自 default.nix
文件中声明的内容?
Nix manual 有一些关于如何组装 .nix-defexpr
的信息:
The Nix expressions in this directory are combined into a single set,
with each file as an attribute that has the name of the file.
不过,它没有提到如果内容本身就是目录会发生什么。但我发现 this GitHub issue 更能解释事情:
- If a directory is a valid expression (i.e. has default.nix) its expression will be added to the set, otherwise it will be traversed
recursively.
- Names of intermediate directories are completely ignored (i.e. do not take any part in attrpaths).
- manifest.nix is recursively ignored.
因此,没有 channels
根属性,因为该文件夹没有 default.nix
表达式。
好的。然后,作为实验,我创建了一个文件夹 .nix-defexpr/foo
,其中包含一个文件 default.nix
,其中包含内容 { zzz = 4; }
。当我执行 nix-env --install -A foo.zzz
我得到:
error: expression does not evaluate to a derivation (or a set or list of those)
也就是说它真的找到了路径!问题是 4
不是推导。
但是,如果我创建另一个文件夹 .nix-defexpr/whatever
并将文件夹 foo
的副本放在那里怎么办?不会有某种名称冲突吗?是的,有:
8f792ff4f96a:~# nix-env --install -A foo.zzz
warning: name collision in input Nix expressions, skipping '/root/.nix-defexpr/whatever/foo'
在我的 NixOS 机器上,我可以使用 nix-env
以两种方式查询 ghc
包:
一个是 nix-env -f '<nixpkgs>' -qaP ghc
,它导致输出
ghc ghc-8.6.5
另一个是 nix-env -qaP ghc
,它导致输出
nixpkgs.ghc ghc-8.6.5
对于第二种情况,我想理解为什么活跃的Nix表达式有一个nixpkgs
根属性。
~/.nix-defexpr
文件夹和几个子文件夹的内容如下:
如何从~/.nix-defexpr
的内容中组装出活跃的Nix表达式?为什么没有 channels
根属性? nixpkgs
根属性的名称是源自 nixpkgs
文件夹的名称,还是源自文件夹的内容,或许源自 default.nix
文件中声明的内容?
Nix manual 有一些关于如何组装 .nix-defexpr
的信息:
The Nix expressions in this directory are combined into a single set, with each file as an attribute that has the name of the file.
不过,它没有提到如果内容本身就是目录会发生什么。但我发现 this GitHub issue 更能解释事情:
- If a directory is a valid expression (i.e. has default.nix) its expression will be added to the set, otherwise it will be traversed recursively.
- Names of intermediate directories are completely ignored (i.e. do not take any part in attrpaths).
- manifest.nix is recursively ignored.
因此,没有 channels
根属性,因为该文件夹没有 default.nix
表达式。
好的。然后,作为实验,我创建了一个文件夹 .nix-defexpr/foo
,其中包含一个文件 default.nix
,其中包含内容 { zzz = 4; }
。当我执行 nix-env --install -A foo.zzz
我得到:
error: expression does not evaluate to a derivation (or a set or list of those)
也就是说它真的找到了路径!问题是 4
不是推导。
但是,如果我创建另一个文件夹 .nix-defexpr/whatever
并将文件夹 foo
的副本放在那里怎么办?不会有某种名称冲突吗?是的,有:
8f792ff4f96a:~# nix-env --install -A foo.zzz
warning: name collision in input Nix expressions, skipping '/root/.nix-defexpr/whatever/foo'