Skip to content

4. Nix ファイルで Nix Shell を定義し、自動で読み込む

Nix ファイルで Nix Shell を定義する

Section titled “Nix ファイルで Nix Shell を定義する”

nix-shell で、Nix のパッケージを一時的にインストールできることを2 章で学びました。

今回は、シェルの定義ファイルを作成して、そこからシェル定義を読み込んでみましょう。

ファイルからシェル定義を読み込むと、以下のようなメリットがあります。

  • 毎回必要なパッケージを自分で打ち込む必要がない
  • プロジェクトで定義ファイルを共有することで、プロジェクトで必要なパッケージをメンバー間で共有できる
  • direnv などのツールを使い、自動でシェルを読み込むことができる

まずはシェル定義ファイルを作成し、動かしてみましょう。詳しい構文は後で説明します。

shell.nix
let
pkgs = import <nixpkgs> {};
in
pkgs.mkShell {
packages = [
pkgs.hello
pkgs.cowsay
pkgs.lolcat
];
}
Terminal window
nix-shell ./shell.nix # ファイル名が与えられないとデフォルトで `shell.nix` を使うので、省略も可能
hello --greeting 'Hello, Nix!'
# -> Hello, Nix!
ls | cowsay | lolcat
exit
hello --greeting 'Hello, Nix!'
# -> hello: command not found

主に pkgs という変数名にされる、 Nixpkgs のライブラリをすべて格納した Attrset に評価されます。これのことを Nixpkgs と呼ぶこともあります。

ここに大量のプログラムと Nix の公式ライブラリ関数がすべて格納されています。

本当はこれ以上分解できるのですが、難しいのでこの単位で捉えても構いません。 一年くらい Nix してるとそのうちわかるかもしれませんね。

詳しい説明
  • import: パスを引数に取り、その場所にある Nix ファイルの中身に展開される builtin 関数。
  • {}: 空の Attrset。 import <nixpkgs> はオプションを取って pkgs を返す関数になるので、すべてのオプションをデフォルトで呼び出す。

<nixpkgs> をさらに分解する

<> 構文: 間に挟まれた文字列に対応する Nix Path を、$NIX_PATH 環境変数などから探してくる構文。

$NIX_PATHkey=URL やチャンネル (たぶん後述) のパスを : で接続した形式になっている。 URL のスキームの区切り (例: http:..., file:...) にも : が使われるので、非常に紛らわしい。

bash
echo $NIX_PATH
# -> nixpkgs=flake:nixpkgs:/nix/var/nix/profiles/per-user/root/channels
# nixpkgs=flake:nixpkgs と /nix/var/nix/profiles/per-user/root/channels に分解できる。

今回の場合は nixpkgs=flake:nixpkgs にマッチするので、どうなるんだろう?

最終的には、 <nixpkgs>/nix/store/(hash)-source というパスになる。このパスの中身は、 nixpkgs のリポジトリのようだ。

Nixpkgs のライブラリ関数の一つで、シェルを表現する Attrset (Derivation と呼ばれる、たぶん後述) を返します。

引数の Attrset のとるオプションには、以下が含まれます:

  • packages: シェルで使用可能にするパッケージのリスト。
  • env: 環境変数を表す Attrset。

Direnv を使って自動で Nix Shell に入る

Section titled “Direnv を使って自動で Nix Shell に入る”
  1. Direnv をインストールします。 https://direnv.net/docs/installation.html
  • Home Manager か NixOS のある方はそれでインストールしてください。
  1. Nix-Direnv をインストールします。 https://github.com/nix-community/nix-direnv
  • Home Manager か NixOS のある方はそれを、ない方は「Install with nix profile」を選択してください。

Direnv は、 .envrc ファイルを使って設定します。まずは、 .envrc を作成しましょう。

.envrc
use nix

Direnv に direnv: error .envrc is blocked. Run direnv allow to approve its content のようなことを言われるので、 direnv allow と実行します。

Terminal window
direnv allow

これで、そのディレクトリに入ったときに自動で Nix シェルが起動するようになりました。

試しに、1個上のディレクトリと行き来してみましょう。

Terminal window
which hello
# -> /nix/store/9bwryidal9q3g91cjm6xschfn4ikd82q-hello-2.12.1/bin/hello
cd ..
which hello
# -> which: no hello in (paths)
cd nix-shell-sample
which hello
# -> /nix/store/9bwryidal9q3g91cjm6xschfn4ikd82q-hello-2.12.1/bin/hello