我在过去注意到,在nix中,./myfile.txt路径类型似乎
/home/myuser/mydir/myfile.txt,并且/nix/store/55j24v9qwdarikv7kd3lc0pvxdr9r2y8-myfile.txt。我想确切地了解什么时候会发生这种情况。
对于包含任何形式的秘密信息的文件来说,这尤其重要,因为/nix/store中的所有文件都是系统上所有用户都可以阅读的。
(在使用nixops时,有一个特殊的“键”特性,请参阅手册中的管理密钥部分,但我认为在nix中何时以及如何进行路径到存储路径复制仍然很重要。)
发布于 2017-05-08 14:33:12
用户clever在#nixos IRC频道上解释道:
当它发生时
当您在${} /nix/store/...字符串插值(例如mystring = "cat ${./myfile.txt} )中使用路径时,扩展到会发生。
当您使用toString 函数时,不会发生这种情况,例如,toString ./myfile.txt不会为您提供指向/nix/store的路径。
例如:
toString ./notes.txt == "/home/clever/apps/nixos-installer/installer-gui/notes.txt"
"${./notes.txt}" == "/nix/store/55j24v9qwdarikv7kd3lc0pvxdr9r2y8-notes.txt"它是如何发生的
55j24v9qwdarikv7kd3lc0pvxdr9r2y8散列部分是从./path引用的文件的内容中提取的,这样当文件发生变化时,它就会发生变化,并且它所依赖的东西也可以相应地重新生成。
将文件复制到/nix/store时发生在nix-instantiate时;对nix表达式的计算仍然是纯功能的(在计算时不进行复制),但是实例化(“构建”)不是。
为了实现这一点,nix中的每个字符串都有一个“上下文”来跟踪字符串所依赖的内容(实际上,它后面有一个.drv路径列表)。
例如,来自"/nix/store/rkvwvi007k7w8lp4cc0n10yhlz5xjfmk-hello-2.10"包的字符串GNU hello具有一些不可见的状态,也就是说它依赖于hello派生。如果该字符串作为stdenv.mkDerivation的输入结束,那么新生成的派生将“神奇地”依赖于正在构建的hello包。
即使您通过builtins.substring处理字符串,这也是可行的。有关如何在第1653行中提取较长字符串的上下文,并将其用作第1657行中的子字符串的上下文,请参见nix的这段代码。
您可以使用builtins.unsafeDiscardStringContext处理字符串的依赖上下文。
在nix代码中发生这种情况
${}插值使用coerceToString,该参数具有默认为true的bool copyToStore参数。
/* String coercion. Converts strings, paths and derivations to a
string. If `coerceMore' is set, also converts nulls, integers,
booleans and lists to a string. If `copyToStore' is set,
referenced paths are copied to the Nix store as a side effect. */
string coerceToString(const Pos & pos, Value & v, PathSet & context,
bool coerceMore = false, bool copyToStore = true);它被实现为这里,并且检查内插的事物是./path,以及复制到/nix/store,正在发生就在下面。
if (v.type == tPath) {
Path path(canonPath(v.path));
return copyToStore ? copyPathToStore(context, path) : path;
}toString是用prim_toString实现的,它为copyToStore参数传递false:
/* Convert the argument to a string. Paths are *not* copied to the
store, so `toString /foo/bar' yields `"/foo/bar"', not
`"/nix/store/whatever..."'. */
static void prim_toString(EvalState & state, const Pos & pos, Value * * args, Value & v)
{
PathSet context;
string s = state.coerceToString(pos, *args[0], context, true, false);
mkString(v, s, context);
}https://stackoverflow.com/questions/43850371
复制相似问题