首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >nix路径类型何时进入nix存储,何时不?

nix路径类型何时进入nix存储,何时不?
EN

Stack Overflow用户
提问于 2017-05-08 14:33:12
回答 1查看 3.1K关注 0票数 22

我在过去注意到,在nix中,./myfile.txt路径类型似乎

  • 有时评估为/home/myuser/mydir/myfile.txt,并且
  • 有时去/nix/store/55j24v9qwdarikv7kd3lc0pvxdr9r2y8-myfile.txt

我想确切地了解什么时候会发生这种情况。

对于包含任何形式的秘密信息的文件来说,这尤其重要,因为/nix/store中的所有文件都是系统上所有用户都可以阅读的。

(在使用nixops时,有一个特殊的“键”特性,请参阅手册中的管理密钥部分,但我认为在nix中何时以及如何进行路径到存储路径复制仍然很重要。)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-05-08 14:33:12

用户clever#nixos IRC频道上解释道:

当它发生时

当您在${} /nix/store/...字符串插值(例如mystring = "cat ${./myfile.txt} )中使用路径时,扩展到会发生

当您使用toString 函数时,不会发生这种情况,例如,toString ./myfile.txt不会为您提供指向/nix/store的路径。

例如:

代码语言:javascript
复制
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,该参数具有默认为truebool copyToStore参数。

代码语言:javascript
复制
/* 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,正在发生就在下面

代码语言:javascript
复制
if (v.type == tPath) {
    Path path(canonPath(v.path));
    return copyToStore ? copyPathToStore(context, path) : path;
}

toString是用prim_toString实现的,它为copyToStore参数传递false

代码语言:javascript
复制
/* 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);
}
票数 32
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43850371

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档