为什么在使用 gemsets 时需要 `bundle exec`?

Why `bundle exec` is needed when using gemsets?

rvm current 说我已经切换到某些特定的 gem 集,gem list 只列出了一个 rake gem,所以我为什么需要前置 bundle exec?

$ rvm current
ruby-2.3.0@rm

$ gem list rake

*** LOCAL GEMS ***

rake (10.4.2)

$ rake
rake aborted!
Gem::LoadError: You have already activated rake 10.4.2, but your Gemfile requires rake 11.1.2. Prepending `bundle exec` to your command may solve this.
/home/rm/.rvm/gems/ruby-2.3.0@rm/gems/bundler-1.12.5/lib/bundler/runtime.rb:35:in `block in setup'
/home/rm/.rvm/gems/ruby-2.3.0@rm/gems/bundler-1.12.5/lib/bundler/runtime.rb:20:in `map'
/home/rm/.rvm/gems/ruby-2.3.0@rm/gems/bundler-1.12.5/lib/bundler/runtime.rb:20:in `setup'
/home/rm/.rvm/gems/ruby-2.3.0@rm/gems/bundler-1.12.5/lib/bundler.rb:95:in `setup'
/home/rm/.rvm/gems/ruby-2.3.0@rm/gems/bundler-1.12.5/lib/bundler/setup.rb:9:in `<top (required)>'
/home/rm/app/releases/20160707125838/config/boot.rb:3:in `<top (required)>'
/home/rm/app/releases/20160707125838/config/application.rb:1:in `<top (required)>'
/home/rm/app/releases/20160707125838/Rakefile:4:in `<top (required)>'
LoadError: cannot load such file -- bundler/setup
/home/rm/app/releases/20160707125838/config/boot.rb:3:in `<top (required)>'
/home/rm/app/releases/20160707125838/config/application.rb:1:in `<top (required)>'
/home/rm/app/releases/20160707125838/Rakefile:4:in `<top (required)>'
(See full trace by running task with --trace)

UPD 让我自己说清楚。 rm gem 集处于活动状态,我只看到其中一个 rake gem (10.4.2)。但是 rake-11.1.2 是与 bundler 一起安装的。当我 运行 bundle exec rake 时, rake-11.1.2 被调用。那么,为什么我在 gem 报告的 gem 列表中看不到它? gem 集合不应该将 gem 集合彼此隔离。

哦,忘了说这是一台生产机器。

正如您在错误中看到的那样,您的 rake 调用需要使用 rake 11.1.2,但您的本地计算机默认为 rake 10.4.2,因此如果不在调用前加上 bundle exec,则使用默认值 (10.4.2) . bundle exec 所做的总是使用项目 gem 文件中指定的 gem 版本,因此使用 bundle exec

始终是最佳实践

可能您没有正确设置gem设置。如果单个 gem 集有相同 gem 的多个版本,您应该使用 bundle exec。尝试为您的项目创建和使用一个特定的 gem 集,如果您没有明确说明 rvm 使用默认的 gems

在开发机器上 bundlergem 安装 gem 的地方安装 gem。您可以在 gem list 的输出中看到它们。但是在生产服务器上,它们通常安装在单独的目录中。这就是 --deployment option particularly does. Or you can change gem's location with --path 选项。