Docs header transparent bg

bundle exec

bundle-exec - バンドルのコンテキストでコマンドを実行する

bundle exec [--keep-file-descriptors] command

説明

このコマンドは、Gemfile(5)で指定されたすべてのgemをRubyプログラムでrequireできるようにして、コマンドを実行します。

基本的に、通常rspec spec/my_spec.rbのように実行するものを、Gemfile(5)で指定され、bundle install(1)でインストールされたgemを使用したい場合は、bundle exec rspec spec/my_spec.rbを実行する必要があります。

bundle execは、実行ファイルがシェルの$PATH上に存在することを要求しません。

オプション

--keep-file-descriptors
すべてのファイルディスクリプタを新しいプロセスに渡します。Bundlerバージョン2.2.26以降はデフォルトでtrueです。falseに設定することは非推奨になりました。

Bundle Install --binstubs

bundle install(1)--binstubsフラグを使用すると、バンドル内のgemから利用可能なすべての実行ファイルを含むディレクトリ(デフォルトはapp_root/bin)が自動的に作成されます。

--binstubsを使用した後、bin/rspec spec/my_spec.rbbundle exec rspec spec/my_spec.rbと同一になります。

環境の変更

bundle execはシェル環境にいくつかの変更を加えた後、指定したコマンドを完全に実行します。

  • bundle execによって呼び出されたコマンド内からbundleにシェルアウトできることを確認します($BUNDLE_BIN_PATHを使用)。
  • バンドルの実行ファイル(railsrspecrackupなど)を含むディレクトリを$PATHに追加します。
  • サブシェルでバンドラーが呼び出された場合、同じGemfileを使用することを確認します(BUNDLE_GEMFILEを設定)。
  • $RUBYOPT-rbundler/setupを追加します。これにより、サブシェルで呼び出されたRubyプログラムがバンドル内のgemを参照できるようになります。

また、Rubygemsも変更します。

  • バンドルにない追加のgemのロードを許可しません。
  • gemメソッドを、要件に一致するgemがバンドル内にある場合は無操作とし、ない場合はGem::LoadErrorを発生させるように変更します。
  • ソースインデックスはバンドラーを使用すると常に固定されているため、Gem.refreshを無操作とし、システムのgemが環境に漏れるのを防ぎます。
  • バンドル内のgemを使用するようにGem.bin_pathをオーバーライドし、システムの実行ファイルが機能するようにします。
  • バンドル内のすべてのgemをGem.loaded_specsに追加します。

最後に、bundle execは、lockファイルとGemfileが一致しない場合、Gemfile.lockを暗黙的に変更します。バンドラーは、gemのグループ、autorequire、プラットフォームなどの情報を決定するためにGemfileを必要とし、その情報はlockファイルには保存されていません。bundle execを正常に実行するには、Gemfileとlockファイルが同期している必要があるため、bundle execは事前にlockファイルを更新します。

読み込み

デフォルトでは、RubyのShebangを持つファイルにbundle execを実行しようとすると、BundlerはKernel.execを使用する代わりに、そのファイルをKernel.loadします。ほとんどの場合、これはパフォーマンスの向上になります。まれに、これにより微妙な副作用($0または__FILE__の正確な内容への依存など)が発生する可能性があり、disable_exec_load設定を有効にすることで最適化を無効にできます。

シェルアウト

サブシェルを開くRubyコード(system、バッククォート、または%x{}など)は、自動的に現在のBundler環境を使用します。現在のバンドルに含まれていないRubyコマンドにシェルアウトする必要がある場合は、ブロックを使用してwith_unbundled_envメソッドを使用します。ブロック内で作成されたサブシェルには、Bundlerがアクティブになる前の環境が与えられます。たとえば、HomebrewコマンドはRubyを実行しますが、バンドル内では機能しません。

Bundler.with_unbundled_env do
  `brew install wget`
end

別のバンドルにシェルアウトする必要がある場合も、with_unbundled_envを使用する必要があります。サブシェルで実行されるバンドラーコマンドは現在のGemfileを継承するため、別のバンドルのコンテキストで実行する必要があるコマンドもwith_unbundled_envを使用する必要があります。

Bundler.with_unbundled_env do
  Dir.chdir "/other/bundler/project" do
    `bundle exec ./script`
  end
end

Bundlerはsystemexecをラップする便利なヘルパーを提供しており、次のように使用できます。

Bundler.clean_system('brew install wget')
Bundler.clean_exec('brew install wget')

Rubygemsプラグイン

現在、Rubygemsプラグインシステムは、Rubyコードがrubygems.rbをrequireすると、インストールされたgemのロードパス上のすべてrubygems_plugin.rbという名前のファイルを必要とします。これには、railsrackuprspecなど、システムにインストールされた実行ファイルが含まれます。

Rubygemsプラグインには任意のRubyコードを含めることができるため、通常はそれ自体またはその依存関係をアクティブ化します。

たとえば、gemcutter 0.5 gemはjson_pureに依存していました。このバージョンのgemcutterがインストールされている場合(この問題のない新しいバージョンもインストールされている場合でも)、Rubygemsはgemcutter 0.5json_pure <latest>をアクティブ化します。

あなたのGemfile(5)にもjson_pure(またはjson_pureに依存するgem)が含まれている場合、システム上の最新バージョンはGemfile(5)内のバージョン、またはGemfile.lockのスナップショットバージョンと競合する可能性があります。

これが発生した場合、バンドラーは次のように表示します。

You have already activated json_pure 1.4.6 but your Gemfile
requires json_pure 1.4.3. Consider using bundle exec.

この状況では、問題のあるgemプラグインを持つ基になるgemを削除する必要があります。一般的に、これらのプラグインの作者(この場合はgemcutter gem)は、より注意深いプラグインを持つ新しいバージョンをリリースしています。

gemプラグインを含むすべてのgemのリストは、次を実行して見つけることができます。

ruby -e "puts Gem.find_files('rubygems_plugin.rb')"

少なくとも、各gemプラグインの最新バージョンを除くすべてを削除し、使用していないgemプラグイン(gem uninstall gem_name)もすべて削除する必要があります。

GitHubでこのドキュメントを編集する(エラーを見つけた場合、または何かが不足している場合)。