bundle-exec – Führen Sie einen Befehl im Kontext des Bundles aus
bundle exec [--keep-file-descriptors] command
Dieser Befehl führt den Befehl aus und macht alle in der [Gemfile(5)][Gemfile(5)] angegebenen Gems für require in Ruby-Programmen verfügbar.
Im Wesentlichen, wenn Sie normalerweise etwas wie rspec spec/my_spec.rb ausgeführt hätten und Sie die in [Gemfile(5)] angegebenen Gems verwenden möchten, [Gemfile( 5)] und über bundle install(1) bundle-install.1.html installiert haben, sollten Sie bundle exec rspec spec/my_spec.rb ausführen.
Beachten Sie, dass bundle exec nicht erfordert, dass eine ausführbare Datei im ` PATH Ihrer Shell verfügbar ist.
Exec begann in Ruby 2.0, nicht standardmäßige Dateideskriptoren zu verwerfen. Wenn dieses Flag übergeben wird, kehrt exec zum Verhalten von 1.9 zurück und übergibt alle Dateideskriptoren an den neuen Prozess.
Wenn Sie das Flag --binstubs in bundle install(1) bundle-install.1.html verwenden, erstellt Bundler automatisch ein Verzeichnis (standardmäßig app_root). /bin), das alle ausführbaren Dateien enthält, die von den Gems im Bundle verfügbar sind.
Nach der Verwendung von --binstubs ist bin/rspec spec/my_spec.rb identisch mit bundle exec rspec spec/my_spec.rb.
bundle exec nimmt eine Reihe von Änderungen an der Shell-Umgebung vor und führt dann den von Ihnen angegebenen Befehl vollständig aus.
Stellen Sie sicher, dass es weiterhin möglich ist, aus einem von bundle exec aufgerufenen Befehl heraus einen Shell-Out an bundle durchzuführen (unter Verwendung von $BUNDLE_BIN_PATH).
Legen Sie das Verzeichnis mit den ausführbaren Dateien (wie rails, rspec, rackup) für Ihr Bundle im ` PATH ab
Stellen Sie sicher, dass der Bundler, wenn er in der Subshell aufgerufen wird, dieselbe Gemfile verwendet (durch Festlegen von BUNDLE_GEMFILE).
Fügen Sie -rbundler/setup zu $RUBYOPT hinzu, um sicherzustellen, dass in der Subshell aufgerufene Ruby-Programme die Gems im Bundle sehen können
Es ändert auch Rubygems:
Das Laden zusätzlicher Edelsteine, die nicht im Paket enthalten sind, ist nicht gestattet
Ändern Sie die gem-Methode so, dass sie eine No-Op-Methode ist, wenn ein Gem, das den Anforderungen entspricht, im Bundle vorhanden ist, und um einen Gem::LoadError auszulösen, wenn dies nicht der Fall ist
Definieren Sie Gem.refresh als No-Op, da der Quellindex bei Verwendung von Bundler immer eingefroren wird und um zu verhindern, dass Gems aus dem System in die Umgebung gelangen
Überschreiben Sie Gem.bin_path, um die Gems im Bundle zu verwenden, sodass ausführbare Systemdateien funktionieren
Fügen Sie alle Edelsteine im Bundle zu Gem.loaded_specs hinzu
Schließlich ändert bundle exec auch implizit Gemfile.lock, wenn die Sperrdatei und die Gemfile nicht übereinstimmen. Bundler benötigt die Gemfile, um Dinge wie die Gruppen eines Gems, autorequire und Plattformen usw. zu bestimmen, und diese Informationen werden nicht in der Sperrdatei gespeichert. Gemfile und Lockfile müssen synchronisiert werden, damit bundle exec erfolgreich ausgeführt werden kann. Daher aktualisiert bundle exec die Lockfile vorher.
Wenn versucht wird, exec mit einem Ruby-Shebang in eine Datei zu bündeln, wird Bundler standardmäßig diese Datei Kernel.load verwenden, anstatt Kernel.exec zu verwenden . In den allermeisten Fällen handelt es sich hierbei um eine Leistungsverbesserung. In seltenen Fällen kann dies zu geringfügigen Nebenwirkungen führen (z. B. Abhängigkeit vom genauen Inhalt von $0 oder __FILE__). Die Optimierung kann durch Aktivieren von deaktiviert werden disable_exec_load-Einstellung.
Jeder Ruby-Code, der eine Subshell öffnet (wie system, Backticks oder %x{}), verwendet automatisch die aktuelle Bundler-Umgebung. Wenn Sie einen Ruby-Befehl ausführen müssen, der nicht Teil Ihres aktuellen Bundles ist, verwenden Sie die Methode with_unbundled_env mit einem Block. Alle innerhalb des Blocks erstellten Subshells erhalten die Umgebung, die vor der Aktivierung von Bundler vorhanden war. Homebrew-Befehle führen beispielsweise Ruby aus, funktionieren aber nicht innerhalb eines Bundles:
Bundler.with_unbundled_env do
`brew install wget`
endDie Verwendung von with_unbundled_env ist auch erforderlich, wenn Sie auf ein anderes Bundle umsteigen. Alle Bundler-Befehle, die in einer Subshell ausgeführt werden, erben die aktuelle Gemfile. Daher müssen Befehle, die im Kontext eines anderen Bundles ausgeführt werden müssen, auch with_unbundled_env verwenden.
Bundler.with_unbundled_env do
Dir.chdir "/other/bundler/project" do
`bundle exec ./script`
end
endBundler bietet praktische Helfer, die system und exec umschließen, und sie können wie folgt verwendet werden:
Bundler.clean_system('brew install wget')
Bundler.clean_exec('brew install wget')Derzeit erfordert das Rubygems-Plugin-System alle Dateien mit dem Namen rubygems_plugin.rb im Ladepfad jedes installierten Gems, wenn jeder Ruby-Code rubygems.rb erfordert >. Dazu gehören im System installierte ausführbare Dateien wie Rails, Rackup und RSpec.
Da Rubygems-Plugins beliebigen Ruby-Code enthalten können, aktivieren sie sich häufig selbst oder ihre Abhängigkeiten.
Beispielsweise war der Edelstein gemcutter 0.5 von json_pure abhängig. Wenn Sie diese Version von Gemcutter installiert hätten (auch wenn Sie auch eine neuere Version ohne dieses Problem hätten), würde Rubygems gemcutter 0.5 und json_pure
Wenn Ihre Gemfile(5) auch json_pure (oder ein Gem mit einer Abhängigkeit von json_pure) enthielt, könnte die neueste Version auf Ihrem System mit der Version in Ihrer Gemfile(5) in Konflikt geraten ) oder die Snapshot-Version in Ihrem Gemfile.lock.
In diesem Fall sagt der Bundler:
You have already activated json_pure 1.4.6 but your Gemfile
requires json_pure 1.4.3. Consider using bundle exec.In dieser Situation möchten Sie mit ziemlicher Sicherheit das zugrunde liegende Gem mit dem problematischen Gem-Plugin entfernen. Im Allgemeinen haben die Autoren dieser Plugins (in diesem Fall das gemcutter-Gem) neuere Versionen veröffentlicht, die bei ihren Plugins sorgfältiger vorgehen.
Sie können eine Liste aller Gems finden, die Gem-Plugins enthalten, indem Sie ausführen
ruby -e "puts Gem.find_files('rubygems_plugin.rb')"Zumindest sollten Sie alle Gem-Plugins bis auf die neueste Version entfernen und auch alle Gem-Plugins entfernen, die Sie nicht verwenden (gem uninstall gem_name).