Tanaka on Rails

行動・努力・俯瞰

bundle exec と bin の違い

$ bin/$ bundle execの違いがよくわからないので調べてみた。

bundle execについて

Gemのパッケージ管理ツールBundlerによって使うことができる。
Gemfileに基づいて実行をするというコマンド。
たとえば$ bundle exec rspecRSpecを実行する際は、アプリケーション内のGemfileに設定してあるバージョンで実行できる。
$ rspecだとローカル環境にインストールされているGemのRSpecを使用することになるため、バージョンが異なったり、インストールされてない場合は実行されない。

binについて

ググってみたがあんまりピンとこなかったが、現場Rails P65 で以下のような記述があり非常にわかりやすかった。

アプリケーションのルートディレクトリ直下のbinディレクトリにあるrailsというスクリプトを呼び出しています。このスクリプトを利用すると、「bundle exec rails」として実行した時と同様に、Gemfileどおりのgemを利用できる環境上でrailsコマンドを実行することができます。
それに加えて、SpringというRailsの起動を効率的に行う機能も組み込まれます。このように、よく使うコマンドを包み込んで使いやすくするスクリプトを「binstub」といいます。

つまりbinディレクトリ以下に設定してあるスクリプト$ bin/railsのように使うことができ、$ bundle exec railsと同じように、そのアプリケーションのGemfileに設定してある環境でコマンドを実行することができるってこと。
また、$ bin/rspecをしてみるとSpring is runningと自動的に設定されることも確認できる。ここが$ bundle execとの違い。

ちなみにrailsコマンドについてはbinをつける必要はないらしい。(つけなくても一緒の挙動らしい)

参考

現場Rails
https://railsguides.jp/initialization.html
https://qiita.com/d0ne1s/items/fa2dafcee02e963fe997
https://github.com/rbenv/rbenv/wiki/Understanding-binstubs
https://techracho.bpsinc.jp/hachi8833/2016_08_24/25037
https://qiita.com/jnchito/items/c5a0848144203dce6e26