我在过去注意到在 nix
中,似乎是 ./myfile.txt
路径类型
-
有时评估为
/home/myuser/mydir/myfile.txt
,和 -
有时候
/nix/store/55j24v9qwdarikv7kd3lc0pvxdr9r2y8-myfile.txt
.
我想知道究竟何时发生这种情况 .
这对于包含任何形式的秘密信息的文件尤其重要,因为 /nix/store
中的所有文件都是系统上所有用户都可以读取的 .
(当使用 nixops
时,为此目的有一个特殊的"keys"功能,请参阅本手册中的Managing keys部分,但我认为在 nix
本身发生这种路径到存储路径复制的时间和方式仍然很重要 . )
1 回答
#nixos
IRC Channels 上的用户clever
解释说:当它发生时
扩展到
/nix/store/...
发生 when you use a path inside ${} string interpolation ,例如mystring = "cat ${./myfile.txt}
.It does not happen when you use the toString function ,例如
toString ./myfile.txt
不会给你指向/nix/store
的路径 .例如:
怎么回事
55j24v9qwdarikv7kd3lc0pvxdr9r2y8
哈希部分取自./path
引用的文件的内容,以便在文件更改时更改,并且依赖于它的内容可以相应地重建 .将文件复制到
/nix/store
时发生在nix-instantiate
; nix表达式的评估仍然是纯粹的功能(在评估时不会发生复制),但实例化("building")则不然 .为了实现这一点,
nix
中的每个字符串都有一个"context"来跟踪字符串所依赖的内容(实际上是它背后的.drv
路径列表) .例如,
GNU hello
包中的字符串"/nix/store/rkvwvi007k7w8lp4cc0n10yhlz5xjfmk-hello-2.10"
具有一些不可见状态,表示它取决于hello
派生 . 如果该字符串作为stdenv.mkDerivation的输入结束,则新建的派生将依赖于正在构建的hello
包 .即使你通过
builtins.substring
搞乱字符串,这也有效 . 请参阅nix的this code,了解如何在第1653行中提取较长字符串的上下文,并将其用作第1657行中子字符串的上下文 .您可以使用
builtins.unsafeDiscardStringContext
删除字符串的依赖关系上下文 .在nix代码中发生的地方
${}
interpolation使用coerceToString,其bool copyToStore
参数默认为true
:它被实现here,并且检查插值的东西是
./path
,并且复制到/nix/store
,正在发生just below:toString
用prim_toString实现,它为copyToStore
参数传递false
: