NixOS で .local/bin ディレクトリを生成して自作スクリプトを保存する方法
概要
前置き
NixOS の home-manager でユーザー環境を管理していますが、設定を編集する都度 cd .dotfiles && home-manager switch flake . && cd
と長いコマンドを実行する必要があるのが少し面倒でした。
そうしたとき、Taskfile(taskコマンド)のfish補完定義を改善してグローバルタスクに対応した | Atusy's blog という記事を読んで、専用のコマンドが簡単に作れることが分かりましたので、これを NixOS の機能を活用しながら応用することにしました。
設定内容は大したものではないですが、NixOS の Tips になるかと思いましたので、備忘録代わりにまとめます。
環境
OS: NixOS on WSL2 (Windows on ARM)
1> nix-shell -p nix-info --run "nix-info -m"
2 - system: `"aarch64-linux"`
3 - host os: `Linux 5.15.167.4-microsoft-standard-WSL2, NixOS, 24.11 (Vicuna), 24.11.717196.9684b53175fc`
4 - multi-user?: `yes`
5 - sandbox: `yes`
6 - version: `nix-env (Nix) 2.24.14`
7 - channels(root): `"nixos-24.11, nixos-wsl"`
8 - nixpkgs: `/nix/var/nix/profiles/per-user/root/channels/nixos`
9
10> home-manager --version
1125.05-pre
シェルスクリプトの作成
NixOS でシェルスクリプトを作成する場合、1つ注意点があります。NixOS は独自のファイル構造を採用して Filesystem Hierarchy Standard - Wikipedia に準拠していないため、冒頭の shebang を #!/bin/bash
と書いても実行時にエラーになります1。
ではどうするかと言いますと、shebang を #!/usr/bin/env bash
とします。これにより、env
コマンド経由で bash が起動しますので、シェルスクリプトのコードが無事に実行されます2。
実際に作成したシェルスクリプト(~/.dotfiles/home-update
)は次のとおりです。
1#!/usr/bin/env bash
2
3cd ~/.dotfiles
4git add .
5home-manager switch --flake .
6cd ~/
スクリプトを作成したら、chmod +x .dotfiles/home-update
コマンドで実行権限を付与します。
設定内容
ここから .dotfiles/home-update
スクリプトのシンボリックリンクを .local/bin
に作成して home-update
コマンドで実行できるよう設定します。
まず、configuration.nix
に environment.localBinInPath = true
を追加して .local/bin
がパスに追加されるようにします。
それから、home.nix
に以下のコードを追加してシンボリックリンクを作成しています。
1home.file.".local/bin/home-update" = {
2 source = config.lib.file.mkOutOfStoreSymlink "${builtins.toString config.home.homeDirectory}/.dotfiles/home-update";
3};
home.file.".local/bin/home-udate" = {}
は、シンボリックリンクとして作成する.local/bin/home-update
の各種設定を宣言する部分です。シンボリックリンクの場所の指定はホームディレクトリからの相対参照にします。source = config.lib.file.mkOutOfStoreSymlink "${builtins.toString config.home.homeDirectory}/.dotfiles/home-update";
の内容は次のとおりです。lib.file.mkOutOfStoreSymlink
関数を使うことで、Nix ストア(/nix/stor
)以外の場所にシンボリックリンクを作成できるようにします。lib.file.mkOutOfStoreSymlink
の引数としてリンク元のパスを渡しますが、パスの直打ちを避けたかったので、${builtins.toString config.home.homeDirectory}
でホームディレクトリのパスを文字列として取得し、そこに.dotfiles/home-update
を繋げることでリンク元のフルパスを作成して関数に渡しています。- 上記の設定を
source
に渡すことで、.local/bin/home-manager
のリンク元を~/.dotfiles/home-manager
に設定しています。
ここまで設定したら cd .dotfiles && git add . && home-manager switch --flake . && cd
コマンドを実行して設定を反映させます。すると、コマンド実行前に .local/bin
ディレクトリが作成されていなかったとしても、ディレクトリが自動的に作成されてシンボリックリンクが配置されます。
これで home-update
コマンドを実行できるようになりました。