bundle exec是否需要’bundler / setup’等效?

这些事情完全相同吗?

  • bundle exec ruby foo.rb启动ruby进程
  • require "bundler/setup"作为foo.rb的第一行

在您的具体示例中,它们可以被认为是相同的,但实际上它们并不相同。

bundle execbundler/setup没有做的环境做了一些更改。 如果你的foo.rb从不运行子shell,或者从不尝试在子shell中运行其他ruby可执行文件,那么两个版本都是等价的(它们将正确加载捆绑的gem并且工作完全相同)。

bundle exec的整个想法是让你能够运行 原本不是用bundler设计的 可执行文件 。 像rspecrailsrackup 。 如果你自己的应用程序( foo.rb )没有尝试运行可能依赖于你的bundle的可执行文件,那么它无论如何都没有区别。 因为您想要使用bundler确保加载正确的gems,并且对于该bundler/setup在您的情况下完全按照预期工作。

在讨论运行ruby系统可执行文件时,从bundler docs :

在某些情况下,如果可执行文件恰好安装在您的系统中并且没有引入任何与您的软件包冲突的gem,那么运行没有bundle exec的可执行文件可能会有效。

然而,这是不可靠的,并且是相当痛苦的根源。 即使它看起来有效,但它可能在将来或其他机器上不起作用。

然后从bundle exec的联机帮助页中,您可以获得一些关于bundle exec实际执行的操作的其他线索:

环境修改

  • 确保它仍然可以从bundle exec调用的命令中进行shell绑定(使用$ BUNDLE_BIN_PATH)
  • 将包含可执行文件的目录(例如rails,rspec,rackup)放在$ PATH上
  • 确保如果在子shell中调用bundler,它将使用相同的Gemfile(通过设置BUNDLE_GEMFILE)
  • 将-rbundler / setup添加到$ RUBYOPT,这可以确保在子shell中调用的Ruby程序可以看到bundle中的gem

因此,如果您在构建应用程序时考虑到捆绑器支持,那么您永远不需要bundle exec您的应用程序。

但是,如果您需要使用其他工具加载您的应用程序代码, 这些工具可能会加载您的应用程序代码之前加载gem(然后可能会引入错误的非捆绑gem),那么您需要使用bundle exec