Nix: The Purely Functional Package Manager

Nix is a powerful package manager for Linux and other Unix systems that makes package management reliable and reproducible. It provides atomic upgrades and rollbacks, side-by-side installation of multiple versions of a package, multi-user package management and easy setup of build environments.

安装

$ curl https://nixos.org/nix/install | sh

使用

  • 搜索包

    $ nix-env -qa hello
    hello-2.10
    

    如果不加关键字,则列出所有:

    $ nix-env -qa | wc -l
    14664
    
  • 安装包

    $ nix-env -i hello
    
  • 更新包

    # 所有
    $ nix-channel --update nixpkgs
    $ nix-env -u '*'
    # 特定
    $ nix-env -u 'hello'
    
  • 删除包

    $ nix-env -e hello
    
  • 回收不用的包

    $ nix-collect-garbage -d
    
  • 添加源

    $ nix-channel --add https://example.com/channels/nixpkgs-unstable
    $ nix-chanel --update
    
  • Generation

    每一次安装/升级/删除都产生一个 generation,可以回滚(--rollback)至上一次操作,也可以切换(--switch-generation)至任意次操作:

    # 回滚
    $ nix-env --rollback
    switching from generation 3 to 2
    
    $ nix-env --list-generations
    1   2018-11-06 23:04:58
    2   2018-11-06 23:04:59   (current)
    3   2018-11-07 19:23:33
    
    $ hello
    Unknown command 'hello'
    
    # 恢复
    $ nix-env --switch-generation 3
    switching from generation 2 to 3
    
    $ nix-env --list-generations
    1   2018-11-06 23:04:58
    2   2018-11-06 23:04:59
    3   2018-11-07 19:23:33   (current)
    
    $ hello
    Hello, world!
    
  • Profile

    切换工作场景。假设单独设置一个开发相关的环境:

    # create profile & install packages
    $ nix-env -p /nix/var/nix/profiles/per-user/<YOUR_NAME>/devel -i nix git gcc cmake ...
    
    # switch profile
    $ nix-env --switch-profile /nix/var/nix/profiles/per-user/<YOUR_NAME>/devel
    
    $ which git
    ~/.nix-profile/bin/git
    

    这里我希望直接 --switch-profile <PROFILE_NAME>,写绝对路径太麻烦。

使用起来感觉比 homebrew 复杂,一系列 nix-* 命令让我想到了 apt。generation 和 profile 这两项功能是亮点,如果包多一点,用户自制包更方便一点,应该还是有机会的。

参考

6 个赞

GNU 有一个包管理 guix 就是基于这个搞的,不过配置语言换成了 scheme(guile), 还为了这个包管理专门弄了一个发型版 guixsd,感觉也挺不错的。

1 个赞

这个包管理器也有发行版本,特色是中心化配置(另一门语言)和发行版本跨版本号升级后的备份(这点不是很清楚了,没用过)。

本质就是一堆软连接

我对pacman无比满意 image

这个难道任何发行版都能用?

我自己实測过在 Gentoo 和 CentOS 用,因為 binary compatibility 和 self contain 的理由自然可以在多数发行版上用,而且还支持编译。原话:

On GNU/Linux, the packages in Nixpkgs are ‘pure’, meaning that they have no dependencies on packages outside of the Nix store. This means that they should work on pretty much any GNU/Linux distribution.

另外官方支持 macOS。

1 个赞

你说软链接是不是可以和指针做类比?

感觉这意味着装一个软件还得装一堆和系统包重复的包……

这就是我不用它的理由。然而对 Haskell 这種沒有 ABI 和 API 兼容可言,自带包管理器做的也差的就不可缺了。

nix的本质就是基于一堆软连接来做版本管理和切换,用一下就知道了

第三方的包管理器都必须这么做吧,比如 Homebrew。如果不自行管理依赖,一旦系统包升级,第三方软件不就全崩了?

Linux 发行版有自己包管理器,所以不太需要第三方包管理器,就算它不会安装和系统重复的包。

Linux的第三方包管理器的话可以直接基于GNU那套,比如pkg-config什么的(这个可能是UNIX都需要支持的?),当然这套不能搞定所有构建方式。。。

Pkgsrc 就可以直接用系统自带的工具链编译而不用自举一份。Portage 也支持利用用户自行安装的软件编译。这个问题主要在于多数 Linux 的软件动态链接了 libC,稍微更新一下就容易 break ABI,BSD 系这种静态链接大部分库的就没有太大的顾虑。

Unix 标准里没有包管理器。

用起来太复杂就会有一堆人拒绝,你看这么多人都在吹 pacman 就知道了。pkgsrc 和 port 这种 old school 的现个都把 pkg_tools 扔了采用了 apt like 的工具界面,至于底下用的机制没有多人用户会在意。

就算在标准里面也不会有多少人去用,就和现在都在吹 git 没几个人知道 Unix 标准的 sccs 一样。

现在都在吹Unix,有谁知道MULTICS

吹 Unix 的没听说过 Multics 才奇怪了,虽然估计他们连 Unix 长什么样都没见过