这些事情完全相同吗?
bundle exec ruby foo.rb
require "bundler/setup"
foo.rb
答案 0 :(得分:23)
在特定的示例中,它们可以被认为是相同的,但实际上它们并不相同。
bundle exec
对bundler/setup
未做出的环境进行了一些更改。如果你的foo.rb
从不运行子shell,或者从不尝试在子shell中运行其他ruby可执行文件,那么两个版本都是等价的(它们都会正确加载捆绑的gem并且工作完全相同)。
使用bundle exec
的整个想法是让您运行可执行文件 最初设计时不考虑使用bundler 。与rspec
,rails
,rackup
一样。如果您自己的应用程序(foo.rb
)没有尝试运行可能依赖于您的捆绑包的可执行文件,那么它无论如何都没有区别。因为您要确保使用bundler,所以您加载了正确的gem,并且bundler/setup
完全符合您的预期。
在谈论运行ruby系统可执行文件时从bundler docs:
在某些情况下,如果可执行文件恰好安装在您的系统中并且没有引入任何与您的软件包冲突的gem,那么运行没有bundle exec的可执行文件可能会有效。
然而,这是不可靠的,并且是相当痛苦的根源。即使它看起来有效,但它可能在将来或其他机器上不起作用。
然后从manpage of bundle exec您可以获得一些关于bundle exec
实际执行的内容的其他线索:
环境修改
- 确保仍然可以从bundle exec调用的命令中捆绑出来(使用$ BUNDLE_BIN_PATH)
- 在$ PATH
上放置包含可执行文件的目录(例如rails,rspec,rackup)- 确保如果在子shell中调用bundler,它使用相同的Gemfile(通过设置BUNDLE_GEMFILE)
- 将-rbundler / setup添加到$ RUBYOPT,这可以确保在子shell中调用的Ruby程序可以看到包中的gem
因此,如果您在构建应用程序时考虑到捆绑程序支持,那么您永远不需要bundle exec
您的应用程序。
但是,如果您需要使用其他工具加载可能会在之前加载gems 的应用代码,那么他们会加载您的应用代码(然后可能导致错误的非捆绑的宝石),然后你需要使用bundle exec
。