NixOS使用fetchFromGithub拉取hosts合并到/etc/hosts报错如何解决
报错核心原因
- 作用域引用错误:
readFile是Nix语言内置函数,归属builtins内置集合,不在NixOS模块的传入参数列表中。你将其写在函数头的参数解构列表里,Nix无法找到对应传入属性,直接触发attribute 'readFile' missing报错。 - 函数名拼写错误:nixpkgs提供的GitHub源拉取函数标准名称为
fetchFromGitHub(GitHub首字母H大写),你编写的fetchFromGithub拼写不匹配。 - 函数调用语法错误:
fetchurl不支持直接传入URL字符串作为位置参数,必须传入包含url属性的集合作为入参。 - 构建规则违反:
fetchFromGitHub不能直接使用master/main这类浮动分支名作为rev参数,也不能长期使用lib.fakeSha256作为哈希值,不符合Nix内容寻址、构建可复现的核心要求。
正确配置实现
首先修正所有函数引用、拼写和语法问题,再补全符合Nix构建要求的固定版本参数:
- 移除参数列表中不存在的
readFile、拼写错误的fetchFromGithub、语法调用错误的fetchurl声明,内置函数直接通过builtins作用域调用即可。 - 所有拉取远程源的调用,首次配置时先将
sha256设为lib.fakeSha256,执行构建时Nix会在报错信息中输出对应源的正确哈希值,直接替换即可。 - 获取GitHub仓库对应分支最新的完整commit哈希,替换
rev字段的"master"值,不要直接使用浮动分支名。
修正后的可运行配置代码如下:
{ lib, fetchFromGitHub, ... }: { networking.extraHosts = let adawayHosts = builtins.readFile (builtins.fetchurl { url = "https://adaway.org/hosts.txt"; sha256 = lib.fakeSha256; # 首次构建后替换为报错输出的正确哈希 }); adguardHosts = builtins.readFile (builtins.fetchurl { url = "https://adguardteam.github.io/AdGuardSDNSFilter/Filters/filter.txt"; sha256 = lib.fakeSha256; # 首次构建后替换为报错输出的正确哈希 }); stevenBlackHosts = builtins.readFile (fetchFromGitHub { owner = "StevenBlack"; repo = "hosts"; rev = "替换为master分支最新的完整commit哈希"; sha256 = lib.fakeSha256; # 首次构建后替换为报错输出的正确哈希 } + "/hosts"); youtubeAdBlockHosts = builtins.readFile (fetchFromGitHub { owner = "creator54"; repo = "youtube_ad_blocklist"; rev = "替换为master分支最新的完整commit哈希"; sha256 = lib.fakeSha256; # 首次构建后替换为报错输出的正确哈希 } + "/blocklist.txt"); in adawayHosts + adguardHosts + stevenBlackHosts + youtubeAdBlockHosts; }
后续维护注意事项
- 如果需要同步hosts文件的最新版本,定期更新对应源的
rev(GitHub源)和sha256值即可,不要为了省事直接写浮动分支名,否则会导致构建不可复现、缓存失效。 - 若需要自动更新,可以搭配定时更新脚本自动拉取最新commit、计算哈希后替换配置中的对应字段,不要在Nix配置内部实现浮动版本的拉取逻辑。
内容的提问来源于stack exchange,提问作者Creator54
相关产品推荐
相关产品推荐

