大概是比 Homebrew 更好用的包管理方案
为什么不用 Brew
目前在 macOS 上的主流包管理方案还是 Homebrew,但是这玩意我觉得是一点都不好用:
- 真的很慢:安装新包通常来说是比较低频的操作,但是 brew 会自作主张给你在安装前检查自己的更新;就算跳过这一步,和其他包管理器相比,从头安装一个包所需要的时间差异也非常大,我是不太能理解这么一件简单的事儿为什么 brew 需要花那么久;
- "污染"系统文件:众所周知,brew 会把东西全部一股脑的装到
/usr/local/bin
中,如果有一些包想作恶会很轻松的混入系统默认 PATH 中,brew 社区运作的模式也无法保证所有包都是安全的,何况还有可能遇到供应链攻击; - 晦涩难懂:Homebrew 用了大量的啤酒生产术语:Formula, Keg, Tap, Cellar, Bottle, Cask, ...对于我这种滴酒不沾的人来说理解门槛确实有点高,得去好好学习一下才知道这些都是啥。
总之 Brew 并不是一个让我用着舒服的包管理器。但是迫于生计需要在 macOS 上搬砖来养活自己,不能说走就走跑去用 Linux 写代码,于是我就把目光转向了 Nix。
Nix 和 NixOS
大概一年前我在苦于无法便捷地管理 10+ 台服务器时发现了 NixOS,有很多文章都详细介绍了 NixOS 的特点,让我心动不已:
- 以
/etc/nixos
为中心,通过配置文件来控制整个系统上安装的软件和他们的配置; - 可重复构建,对于相同的配置文件,构建出来的操作系统也是一致的*;
- NixOS 使用的包管理器的配置语言 Nix 图灵完备,配置得当我可以在一个 git 仓库中维护我所有服务器的配置,可以最大化共享基础配置,同时记录所有历史版本方便回滚和调试。
- Nix 是函数式的!非常有意思不是吗
* 当然和大部份包管理器一样,如果没有锁其实也并不能保证这一点
在后来的一段时间里我逐步用 NixOS 替换了我大部分服务器上的 Debian。期间我注意到 NixOS 的下载页面中,Nix (the package manager) 是有 macOS 版本的:
于是就计划好了,之后一定要把 brew 从我的系统中彻底抹掉。
替换契机
公司有一个政策:购入三年的 MacBook 产品可以申请到期更换,如果想要甚至可以选择将这台打工电脑回购。满三年之后我自然是立即和 IT 发起了到期更换流程,这台 Intel MacBook Pro 虽然配置了 i7 + 32G,但是用起来依然是卡到爆炸,写代码随时处在崩溃边缘 (:з」∠)
申请当天 IT 就通知我可以来领电脑了。换来的新电脑还是 16 英寸的 MacBook,配备了 M2 处理器和 32G 的内存,整体上非常符合我的期待。至于软件,我不打算从旧的 Intel Mac 上迁移数据,毕竟跨了架构,总感觉会不靠谱。于是这次我就没有安装 brew,准备小试一下不在 NixOS 中使用 Nix。
安装 Nix
就和上面官网截图中介绍的一样,Nix 的安装也是直接用 curl 下载脚本执行来完成的。
less
sh <(curl -L https://nixos.org/nix/install)
不过和大部份"一键脚本"还不太一样,Nix 会在安装过程中详细的输出了自己需要干什么,特别是用到 sudo 的时候:
安装完成之后,我们就可以在终端使用 nix
命令了:
nix 和 brew 比起来有一个很好的地方,就是他的安装的文件都是放在一个 APFS 容器中,如果想要删除 Nix 很方便:删掉容器就好了。
到此为止我们就已经安装完成了 nix 这个包管理器,但是距离像 NixOS 一样用一个 configuration.nix
管理大部份软件还有点区别。
安装 nix-darwin
nix-darwin 把 NixOS 的软件管理模式复刻到了 macOS 上,我们可以用 nix 很方便的安装 nix-darwin
:
bash
nix-build https://github.com/LnL7/nix-darwin/archive/master.tar.gz -A installer
./result/bin/darwin-installer
安装完成之后,我们就可以在 ~/.nixpkgs
中发现这个 darwin-configuration.nix
了:
ini
{ config, pkgs, ... }:
{
environment.systemPackages = [
pkgs.vim
];
services.nix-daemon.enable = true;
programs.zsh.enable = true; # default shell on catalina
system.stateVersion = 4;
}
因为我是一个臭写 HTML 的,所以需要安装 node
,同时我更习惯使用 GNU 的 coreutils 而不是 BSD 的,所以我将这个配置调整至如下:
ini
{ config, pkgs, lib, ... }:
{
nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [
"unrar"
];
environment.systemPackages = with pkgs; [
vim ffmpeg-full coreutils gnugrep gnused gawk htop mtr
smartmontools neofetch rsync p7zip hugo ncdu
ipmitool iperf3 wireguard-tools jq p7zip unrar
];
services.nix-daemon.enable = true;
programs.zsh.enable = true;
system.stateVersion = 4;
}
之后只需要执行 darwin-rebuild switch
即可让 darwin-nix
完成软件的安装和配置(我这里出于使用习惯,没有使用配置的能力)。完成之后所有的软件就都在 PATH 中了:
看日志不难注意到 /Applications/Nix Apps
这个目录的存在,实际上不只是命令行软件,GUI 软件也可以通过 Nix 安装,比如这个叫 kitty 的终端模拟器。