Nix表达式
一个尼克斯的表达就像任何编程语言的表达:任何计算结果为数值或功能。在这种情况下,值也可以是列表或集合。由于Nix模块(扩展名为的文件.nix
)可以包含任何Nix表达式,因此您希望NixOS配置文件(/etc/nixos/configuration.nix
)包含单个Nix表达式作为其文件内容。
NixOS配置文件包含以下格式的Nix表达式:
{config, pkgs, ...}: { /* various configuration options */ }
如果仔细观察,您会发现它是一个函数,因为函数遵循形式pattern: form
。您还可以看到它是一个接受集合并返回集合的函数。例如,如果您有一个函数f = {x, y}: {a = x + y;}
,则可以将其称为as f {x=1; y=2;}
并获取set {a=3;}
。
所以这意味着在调用时nixos-rebuild switch
,某些调用带有包含属性config
和的集合的NixOS配置文件中的函数pkgs
。
进口货
下面的例子./hardware-configuration.nix
,简单的方法来提取的软件包列表到一个单独的模块packages.nix
就是翻录environment.systemPackages
选项,并把./packages.nix
进入imports
选项。您/etc/nixos/configuration.nix
将看起来像:
{ config, ... }:
{
imports =
[ # Include the results of the hardware scan.
./hardware-configuration.nix
# Include the package list.
./packages.nix
];
# SOME STUFF
# SOME STUFF
}
您/etc/nixos/packages.nix
将看起来像:
{ pkgs, ... }:
{
environment.systemPackages = with pkgs; [ emacs gitFull ];
}
这是如何运作的?运行时nixos-rebuild switch
,该过程将评估Nix表达式并决定安装程序包等configuration.nix
具有一组属性的调用,其中一些属性是config
and pkgs
。
它发现属性imports
返回set里面,所以它的计算结果中的模块,每一个尼克斯表达imports
使用相同的参数(包含config
,pkgs
等)。
您必须在pkgs
中将函数作为参数(或者从技术上来说是集合的属性,而它本身就是一个参数)packages.nix
,因为从Nix语言的角度来看,该过程可能会或可能不会使用集合调用函数包含pkgs
。如果不是,那么在运行时将引用什么属性with pkgs
?
您还必须使用省略号,因为该函数可能会使用其他属性(而不仅仅是)来调用pkgs
。
为什么没有pkgs
在configuration.nix
?您可以使用它,但是如果您没有在文件中的任何位置引用它,则可以安全地省略它,因为省略号始终会包含它们。
通过调用外部函数更新属性
另一种方法是制作一个返回带有某些属性的集合的函数,然后将该属性的值放入其中environment.systemPackages
。这是您的configuration.nix
:
{ config, pkgs, ... }:
{
imports =
[ # Include the results of the hardware scan.
./hardware-configuration.nix
];
# SOME STUFF
environment.systemPackages = import ./packages.nix pkgs;
# SOME STUFF
}
您的packages.nix
:
pkgs: with pkgs; [ emacs gitFull ]
import ./packages.nix pkgs
表示:加载并返回Nix表达式./packages.nix
,由于它是一个函数,请使用参数调用它pkgs
。with pkgs; [ emacs gitFull ]
是with表达式,它将分号之前的表达式的范围带到分号之后的表达式。没有它,它将是[ pkgs.emacs pkgs.gitFull ]
。