fish shellでrbenvを使うための手順と、ここに至るまでに得られた知見について書きました。
環境
- Ubuntu 16.04
- fish 2.7.0
-
fisherman 2.13.2 - fishのプラグインマネージャ
- rbenvプラグイン - rbenvに関する細々した設定を裏でやってくれる
- rbenv 1.1.1-6-g2d7cefe
rbenv本体と区別するため、fishermanプラグインの方は「rbenvプラグイン」と記載します。
導入の流れ
rbenvを入れる
$ git clone https://github.com/rbenv/rbenv.git ~/.rbenv
通常はこのあとに環境変数を足したりしますが、rbenvプラグインがそのあたりをやってくれるので、これだけでOKです。1
fishを入れる
fishのリポジトリを追加してaptでインストールします。
$ sudo apt-add-repository ppa:fish-shell/release-2
$ sudo apt-get update
$ sudo apt-get install fish
fishの公式ページに各環境用の導入方法が書いてあるので、ubuntu以外はそちらを参照してください。
fishermanを入れる
プラグインマネージャのfishermanを入れます。
fishermanの実体はfishスクリプト1個だけです。
$ curl -Lo ~/.config/fish/functions/fisher.fish --create-dirs https://git.io/fisher
rbenvプラグインを入れる
fishermanでrbenvプラグインをインストールします。
fisher install rbenv
が本来の書き方ですが、installは省略できます。
$ fish
~> fisher rbenv
~>
となっている部分はfish内での操作です。
rbenvプラグインのインストール中に下記のようなエラーが出ると思います。
rbenv: command not found. See https://github.com/rbenv/rbenv
The program 'rbenv' is currently not installed. You can install it by typing:
sudo apt install rbenv
~/.config/fish/functions/rbenv.fish (line 8):
command rbenv "$command" $argv
^
in function “rbenv”
called on line 1 of file ~/.config/fish/completions/rbenv.fish
with parameter list “commands”
in command substitution
called on line -1 of file ~/.config/fish/completions/rbenv.fish
from sourcing file ~/.config/fish/completions/rbenv.fish
called on line 839 of file ~/.config/fish/functions/fisher.fish
in function “__fisher_plugin_enable”
called on line 445 of file ~/.config/fish/functions/fisher.fish
with parameter list “/home/ubuntu/.config/fisherman/rbenv”
in function “__fisher_install”
called on line 274 of file ~/.config/fish/functions/fisher.fish
with parameter list “rbenv”
in function “fisher”
called on standard input
with parameter list “rbenv”
rbenvプラグインがrbenvの実体を見つけられないのでエラーになっています。
次項の設定ファイルを追加すれば解消します。
conf.dに設定ファイルを追加
~/.config/fish/conf.d/
に設定ファイルを1つ追加します。理由は後述。
set -x PATH $HOME/.rbenv/bin $PATH
rbenvのインストール先を環境変数PATHに追加しています。
これで動くようになったはず。
おまけ
fishの挙動
fishのお作法では、.bashrc
等の代わりにconfig.fish
というファイルを使います。個人用の設定はここに書く、というルールです。
本来はrbenvのパスもconfig.fish
に書くべきなのですが、fishが設定ファイルを読み込む順番の兼ね合いで不都合が出てしまいます。
以下は公式ドキュメントでの記載。
Configuration files are evaluated in the following order:
- Configuration shipped with fish, which should not be edited, in $__fish_datadir/config.fish (usually /usr/share/fish/config.fish).
- System-wide configuration files, where administrators can include initialization that should be run for all users on the system - similar to /etc/profile for POSIX-style shells - in $__fish_sysconfdir (usually /etc/fish/config.fish);
- Configuration snippets in files ending in .fish, in the directories:
- $XDG_CONFIG_HOME/fish/conf.d (by default, ~/.config/fish/conf.d/)
- $__fish_sysconfdir/conf.d (by default, /etc/fish/conf.d)
- /usr/share/fish/vendor_conf.d (set at compile time; by default, $__fish_datadir/conf.d)
- User initialization, usually in ~/.config/fish/config.fish (controlled by the XDG_CONFIG_HOME environment variable).
簡単にまとめるとこんな感じで、上から順に読み込まれます。
- fish組み込みの設定ファイル (編集するべきじゃないファイル)
- システム全体向け設定 /etc/fish/config.fishなど
- 個人向けスニペット ~/.config/fish/conf.d/
- 個人向け設定 ~/.config/fish/config.fish
000-env.fishを入れる理由
rbenvプラグインは3つ目のconf.d/にインストールされるのですが、上記の通りconf.d/の中はconfig.fishよりも先に読み込まれます。
rbenvプラグインが動くのに環境変数PATHの設定が必要だけど、環境変数PATHを書くべきconfig.fishはrbenvプラグインよりも後に読み込まれるという悲劇!!
過去にこの仕様に関するIssueも上がっていたみたいです。
Document conf.d / config.fish sourcing order #3099
結局、conf.d/の中で一番早く実行されるような名前のファイル(000-env.fish)を作り、conf.d/内のスニペットが依存している環境変数等は全部そこに書いてしまおう、という対応が定番になったようです。
-
ruby-buildとかコンパイラの手順は、今回の本筋から外れるので省いています。 ↩