h3pei.tech
お仕事のご依頼
2020-12-29

rbenv rehashをちゃんと理解する

rbenv の rehash というコマンドについてちゃんと理解するべく調べたのでまとめる。なお調べたのはバージョン1.1.2の rbenv。

$ rbenv --version
rbenv 1.1.2

もしかすると間違っている部分があるかもしれないので、気づいた方はコメントなどいただけるとありがたい。

rbenv rehash とは何か

rbenv rehash コマンドを実行すると、大まかには ~/.rbenv/versions/*/bin/ 以下のファイルを ~/.rbenv/shims/ 以下にコピーする。

なぜコピーする必要があるかというと、通常 PATH が通っているのは ~/.rbenv/shims 以下となっているからで、ここにコピーしないと rspec とか rubocop といった Gem が提供するコマンドを実行できないからである。

rbenv init がやっていること

ここで、「rbenv は使っているけど ~/.rbenv/shims に PATH を通した記憶なんて無いぞ」という人もいるかもしれないが、zshrc や bashrc といったシェル起動時に読み込まれるファイルに eval "$(rbenv init -)" と書いた記憶は無いだろうか?

README にちゃんと書かれているのだが、rbenv init - を実行することで、以下のことがなされている。

  • (1) ~/.rbenv/shims を環境変数 PATH の先頭に追加する
  • (2) コマンドの補完用のシェルスクリプトを読み込む
  • (3) shim の rehash、すなわち rbenv rehash の実行
  • (4) sh dispatcher をインストールする

ここで大事なのは (1) のところで、環境変数 PATH へ shims のパスを追加するということを rbenv init - により行われているということだ。

いつ rbenv rehash を実行すればいいか

ここまでの話を踏まえると、実行コマンドを含む Gem (rspec, rubocop, etc..) をインストールした場合には、rbenv rehash コマンドを実行しないといけないことが想像できると思う。

なぜならば、gem install xxx と実行したときには ~/.rbenv/versions/*/bin/ の方にしかインストールされず、そこに配置された実行ファイルをパスの通っている ~/.rbenv/shims 以下にコピーしないと実行できないからだ。

…と自分は考えたのだが、この理解は少し間違っていることが後から判明した。

なぜか? 実は rbenv は gem install xxx をしたタイミングで hook スクリプトを噛ませていて、それが自動的に rbenv rehash を実行していたのである。よって自分で明示的に rbenv rehash を実行する必要はない。

rbenv の歴史はあんまり調べてないのでよく知らないのだけど、もともとは rbenv-gem-rehash という rbenv plugin があって、それがこの動きをしていたのだけれど、今は rbenv の core に移植されているということのようだ。

実際に試してみた

実際に、gem install をしたときに自動で rbenv rehash が実行されていることを確認したのでご紹介。 今回は、今の自分の環境にはインストールされていなかった colorls という gem を使って確認する。

まず、gem install 前の状態。colorls は存在しない。

$ ruby -v
ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-darwin18]

$ ls ~/.rbenv/shims/ | grep colorls
# => 結果なし

colorls を install する。

$ gem install colorls

Fetching colorls-1.4.3.gem

..snip..

Successfully installed colorls-1.4.3
Parsing documentation for colorls-1.4.3
Installing ri documentation for colorls-1.4.3
Done installing documentation for colorls after 0 seconds
1 gem installed

shims 以下を見てみると、すでにいることが確認できる。

$ ls ~/.rbenv/shims/ | grep colorls
colorls

当然、コマンドの実行もできる。

2020-12-29-01.png
colorlsコマンドの実行結果

rehash をいつ実行するか?の考察

このプラグインのおかげもあり、rbenv rehash コマンドを明示的に実行しないといけないケースはそんなに多くないんじゃないかと思う。

そもそも、ログインシェル起動時のタイミングで rbenv init - により自動で rehash は実行されているので、コマンド実行するよりも新規でセッションを立ち上げたほうが楽な気すらする(tmux とか使っていると特に)。

新しいバージョンの ruby をインストールしたときくらいかな?と今は考えている。

まとめ

  • rbenv rehash によって、rspecrubocop といったコマンドが実行できるようになる
  • rbenv rehash は rbenv init のタイミングや gem install のタイミングで裏で動いているので、明示的に実行しないといけないケースは少なそう

rbenv、よくできたツールだなぁとしみじみ思った。

h3pei's icon

h3pei

フリーランスのソフトウェアエンジニア。Ruby / Rails アプリケーションの開発が得意領域。設計・実装・運用まで含めてプロダクト開発が好きです。

Questalという目標達成コミュニティサービスを開発しました。仲間と一緒に目標達成に取り組みたい方はぜひご利用ください。

お仕事のご依頼
GitHubnoteX

関連記事