Plan 9とGo言語のブログ

主にPlan 9やGo言語の日々気づいたことを書きます。

Mac OS XでNixパッケージマネージャを使う

この記事はQiitaで公開されていました

Nixパッケージマネージャは、純関数型OSと言われているNixOSで使われているパッケージングシステムです。上書き更新を行わず、ユーザ単位でパッケージを管理できるのが良い所かなと思います。名前から、Plan 9由来のNixを連想しますが、NixOSとNixは特に関係がありません。

NixOSについては、古い記事ですが、@ITのWeeklyランキングで触れらてているのが分かりやすいかなと思います。

パッケージ検索Web UI

チートシート

インストール

NixOSの公式案内の通り行います。

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

このコマンドは、

  1. 最新の配布物を取得して展開する
  2. 配布物の中にある*/installを実行する

というように、2段階で処理されています。処理が終われば、/nix以下にパッケージ用のファイルが用意され、/etc/profileに、Nixの環境変数を設定するコードが追加されます。

/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh

https://nixos.org/nix/installは、rootでの実行をサポートしていません。なのでsudoをつけて実行するとエラーになります。

$HOME以下には、.nix-profile, .nix-defexpr等が作成されます。

.nix-defexprディレクトリにはパッケージ一覧(実態は/nix以下へのリンク)が入っています。利用可能なパッケージが入っています。.nix-channelsは1行に1つチャンネルURLが入っています(デフォルトは1つ)。nix-channel --addで追加できるみたいですが、試していません。

シングルユーザとマルチユーザ

上記のインストールスクリプトで構築される環境はマルチユーザ環境です。Nixpkgsはこの他にシングルユーザインストールが可能ですが、これを行うには手作業でコマンドを実行していく必要があります。以下の記事に詳しく書かれているので、興味があれば参照してください。

チャンネルの一覧取得

現在登録中のチャンネル一覧を取得します。Homebrewのbrew tapが近いかもしれません。

nix-channel --list

最初はnixpkgsだけ登録されています。

パッケージ一覧のアップデート

Homebrewでいうとbrew updateに該当します。

nix-channel --update [channel-name]

アップデートしたパッケージ一覧は、ユーザ単位で世代として全て残ります。パッケージ一覧が更新された世代を確認する場合、nix-env --list-generationsディレクトリを渡します。

nix-env --list-generations -p /nix/var/nix/profiles/per-user/$USER/channels

また、特定の世代まで戻したい場合は、nix-channel --rollbackを使います。

nix-channel --rollback [generation]

世代の管理については、インストールの項目あたりで書いています。

パッケージ一覧の確認

ユーザにインストールされているパッケージ一覧を表示します。

nix-env -q
nix-env --query --installed

インストール可能なパッケージ一覧を表示します。

nix-env -qa
nix-env --query --available

また、-sオプションを与えると、パッケージ名の前にアルファベット3文字のステータスが表示されます。

nix-env -qs 
nix-env --query --status

ステータスは3文字あります。

文字 意味
I-- 現在のユーザ環境にインストールされている
-P- システムにインストールされている
--S 代替derviationが存在する

基本的に、Iが立っている場合は同時にPも立っています。derivationとは、Cでいうと .o ファイルのようなもので、.cファイルに相当するのはNix言語で書かれたパッケージ情報です。

パッケージ一覧を絞り込みする場合は、引数に正規表現を与えます。

nix-env -q '.*ansible.*'

例えばpython2.7-ansible-v2.0.0.2のように、各種バージョンも込みでパッケージ名になっているため、上記の例でnix-env -q 'ansible.*としてもマッチしません。

他にも、-f オプションを使って、独自にダウンロードしておいたパッケージをインストールできたりします。

パッケージのインストール

Homebrewのbrew installに対応します。

nix-env -i python2.7-ansible-v2.0.0.2
nix-env --install python2.7-ansible-v2.0.0.2

インストールが終われば、インストール前よりも1つ新しい世代として管理されます。世代の確認はnix-env --list-generationsで行います。

nix-env --list-generations

アップグレード可能なパッケージの調査

Homebrewのbrew outdatedに相当します。

nix-env -u --dry-run
nix-env --upgrade --dry-run

インストールされているパッケージで、アップデート可能なものがリストされます。--dry-run自体はアップデートを調べるものではなく、コマンドの結果、何が行われるかを確認するためのオプションです。--upgradeに限らず、--install--rollbackなどNixストアを更新するコマンドでも使えます。

パッケージのアップグレード

Homebrewのbrew upgradeに該当します。インストール時と異なり、パッケージのバージョンを省略します。

nix-env -u python2.7-ansible
nix-env --upgrade python2.7-ansible

パッケージのロールバック

パッケージの状態を1つ前の世代に戻します。

nix-env --rollback

このコマンドは、あくまで世代を戻すだけで、パッケージを指定して以前のバージョンに戻すものではありません。Nixはユーザにインストールされているパッケージ全体をまとめて世代として管理するため、個別に戻すことははできません。世代を2世代以上前に戻す場合は、nix-pkg --switch-generationの方が便利です。

また、世代を戻した場合、不要になった世代を削除するために

nix-env --delete-generations [generation]

コマンドが使えます。[generation]にはいくつかのパターンが使えます。

generation 意味
old 最新の世代だけ残して削除
数字 該当する世代のみ削除
数字+d 数字の数以上日数が経過した世代を削除

パッケージのアンインストール

Homebrewのbrew uninstallに該当します。

nix-env -e python2.7-ansible-v2.0.0.2
nix-env --uninstall python2.7-ansible-v2.0.0.2

ユーザ環境から削除されますが、まだ他のユーザが使っているかもしれないため、Nixストア/nixにはファイルが残り続けます。

ガベージコレクション

Nixは全てのパッケージを/nix以下で管理し、基本的には削除しません。そのため、すでに誰も使っていないパッケージであっても残ってしまうため、ディスク容量が気になるならガベージコレクションを行う必要があります。

nix-store --gc

または

nix-collect-garbage -d

事前に、削除されるパッケージを確認したい、または、現在アクティブなパッケージを確認したい場合は、--print-deadまたは--print-liveオプションが利用できます。

nix-store --gc --print-live
nix-store --gc --print-dead

参考情報