在WSL与Nix环境中,`.: File exists`错误的成因是什么?
ghcWithPackages时出现".: File exists"错误的原因 首先还原你遇到的场景:在WSL的Shell里执行这条命令时触发了错误:
nix-shell -p 'haskell.packages.ghc822.ghcWithPackages (p: with p; [text])' --run ghci -j4
对应的错误输出片段:
these derivations will be built: /nix/store/qkbijf516579sf5654i75g0nvkyk8f08-ghc-8.2.2-with-packages.drv
building '/nix/store/qkbijf516579sf5654i75g0nvkyk8f08-ghc-8.2.2-with-packages.drv'...
.: File exists
..: File exists
.: File exists
..: File exists
lib: /nix/store/2dn56f3pvazrfqpxl9629d94v323crq2-text-1.2.2.2/lib
nix-support: /nix/store/2dn56f3pvazrfqpxl9629d94...
核心成因拆解
这个错误的根源是老版本Nix Haskell工具链构建脚本的小缺陷:
当ghcWithPackages生成带有额外包(这里是text)的GHC环境时,它的构建逻辑会尝试在临时构建目录中创建指向依赖包资源的符号链接,其中错误地包含了对当前目录(.)和上级目录(..)的链接操作。
但这两个目录是类Unix文件系统中默认存在的——任何目录下必然有.(指向自身)和..(指向父目录),所以当脚本尝试创建这两个链接时,就会触发"File exists"的冲突错误。
额外影响因素:WSL环境
纯Linux环境下,这个错误可能会被构建脚本忽略或者静默处理,但WSL的文件系统是Linux子系统与Windows宿主文件系统的混合实现,它的文件存在性检查逻辑比纯Linux更严格,导致这个原本可能被掩盖的错误被直接输出了出来。
简单来说,就是旧版构建脚本的逻辑bug,加上WSL文件系统的严格性,共同导致了你看到的这些错误提示。
内容的提问来源于stack exchange,提问作者Wizek

