bundle exec rake 是啥意思?

Posted

技术标签:

【中文标题】bundle exec rake 是啥意思?【英文标题】:What does bundle exec rake mean?bundle exec rake 是什么意思? 【发布时间】:2011-09-29 03:24:05 【问题描述】:

bundle exec rake db:migrate 是什么意思?或者只是bundle exec rake <command>

我了解bundle 负责维护 Gemfile 中的内容。我知道“执行”这个词是什么意思。我知道rake 维护着你可以做的所有不同的脚本操作,我知道db:migrate 就是其中之一。我只是不知道所有这些词在一起做什么。为什么要使用bundle 执行rake 执行数据库迁移?

【问题讨论】:

【参考方案1】:

我没怎么用过bundle exec,但现在正在设置它。

我遇到过使用错误的 rake 并浪费大量时间来追踪问题的情况。这可以帮助您避免这种情况。

以下是设置 RVM 的方法,以便您可以在特定项目目录中默认使用 bundle exec

https://thoughtbot.com/blog/use-bundlers-binstubs

【讨论】:

【参考方案2】:

您正在一个程序上运行bundle exec。该程序的创建者在某些版本的 gem 可用时编写了它。 Gemfile 程序指定了创建者决定使用的 gem 的版本。也就是说,脚本可以针对这些 gem 版本正确运行。

您的系统范围的 Gemfile 可能与此 Gemfile 不同。您可能有较新或较旧的 gem,而这个脚本不能很好地使用。这种版本差异可能会给您带来奇怪的错误。

bundle exec 帮助您避免这些错误。它使用脚本的 Gemfile 中指定的 gem 来执行脚本,而不是系统范围的 Gemfile。它使用 shell 别名的魔力执行某些 gem 版本。

在the man page 上查看更多信息。

这是一个 Gemfile 示例:

source 'http://rubygems.org'

gem 'rails', '2.8.3'

在这里,bundle exec 将使用 rails 版本 2.8.3 执行脚本,而不是您可能已在系统范围内安装的其他版本。

【讨论】:

我比 OP 选择的答案更喜欢这个答案:D!更清晰。 所以补充一下这个例子:如果这个人只是简单地运行rake db:migrate而忽略bundle exec,那么它将使用系统范围的Gemfile执行,其中一个可能有1.5.2(最新)的机架? 更好的答案,有具体的例子。 所以bundle exec 在您的应用程序的 Gemfile 中使用“应用程序特定”的本地 gem,如果您使用 gem install a_certain_gembundle 使用“机器特定”的全局 gem。本地与全球 比选择的答案要好得多。【参考方案3】:

当您直接运行 rake 任务或执行 gem 的任何二进制文件时,不能保证该命令将按预期运行。因为您可能已经在系统上安装了相同的 gem,其版本为 1.0,但在您的项目中,您的版本更高,例如 2.0。在这种情况下,您无法预测将使用哪一个。

要强制执行所需的 gem 版本,您可以借助 bundle exec 命令在当前包的上下文中执行二进制文件。这意味着当您使用 bundle exec 时,bundler 会检查为当前项目配置的 gem 版本并使用它来执行任务。

我还写了一篇关于它的post,它还展示了我们如何避免使用 bin 存根来使用它。

【讨论】:

【参考方案4】:

bundle exec 是一个Bundler 命令,用于在当前包的上下文中执行脚本(来自您目录的Gemfile)。 rake db:migrate 是脚本,其中 db 是命名空间,migrate 是定义的任务名称。

所以bundle exec rake db:migrate 在当前包的上下文中使用命令db:migrate 执行rake 脚本。

至于“为什么?”我会引用bundler page:

在某些情况下,运行不带bundle exec 的可执行文件可能会起作用,前提是该可执行文件恰好安装在您的系统中并且没有拉入任何与您的捆绑包冲突的 gem。

但是,这是不可靠的,并且是相当痛苦的根源。即使它看起来可以正常工作,但将来或在另一台机器上可能无法正常工作。

【讨论】:

这是否意味着我们应该始终运行 bundle exec,我使用 ruby​​ 版本管理器安装 ruby​​ 和 ruby​​ on rails。 @Edmund “bundle”是一个英文单词,意思是一组相似的东西,通常整齐地捆绑在一起。具体在这个问题中,它指的是一组 Gems(自包含的 ruby​​ 代码库)。Bundler 是我们在这里用来管理 Gems 的软件的名称。 bundle 是 Bundler 使用的命令。 我的印象是,每当我们 cd 到带有 Gemfile 的文件夹时,shell 将自动使用 Gemfile 中指定的版本(例如 Ruby 版本)。基于这个假设,我认为 rake db:migrate 在没有 bundle exec 的情况下总是可以正常运行。 CMIIW @PahleviFikriAuliya 仅当您的项目根目录中有 .ruby-gemset 文件时才适用。如果使用 RVM,还有一个 .ruby-version 文件可以设置您的 ruby​​ 版本。 他们本可以将其称为“本地”或“全局”以更加不言自明……就像 npm 进行常规安装和 -g 安装一样。他们也可以选择较短的版本作为使用频率更高的版本(本地版本)。【参考方案5】:

当您的 gemfile.lock 在您的机器上安装了不同版本的 gem 时,这种情况经常出现。运行 rake(或 rspec 或其他)后可能会收到警告,例如:

You have already activated rake 10.3.1, but your Gemfile requires rake 10.1.0. Prepending "bundle exec" to your command may solve this.

前置bundle exec 告诉捆绑器执行此命令,而不管版本差异如何。并不总是有问题,但是,您可能会遇到问题。

幸运的是,有一个 gem 可以解决这个问题:rubygems-bundler。

$ gem install rubygems-bundler$ $ gem regenerate_binstubs

然后再试试你的 rake、rspec 或其他任何东西。

【讨论】:

在 2020 年仍然是一个很好的解决方案。【参考方案6】:

可能应该提到的是,有一些方法可以省略 bundle exec(它们都在 Michael Hartls Ruby on Rails Tutorial 书中的第 3.6.1 章中说明)。

最简单的方法是使用足够最新的 RVM 版本 (>= 1.11.x)。

如果您受限于 RVM 的早期版本,您始终可以使用calasyr 也提到的这种方法:

$ rvm get head && rvm reload
$ chmod +x $rvm_path/hooks/after_cd_bundler
$ bundle install --binstubs=./bundler_stubs

bundler_stubs 目录也应添加到.gitignore 文件中。

如果您不使用 RVM,第三种选择是使用 rubygems-bundler gem:

$ gem install rubygems-bundler
$ gem regenerate_binstubs

【讨论】:

【参考方案7】:

这意味着使用 bundler 知道的 rake 并且是 Gemfile 的一部分,而不是 bundler 不知道的任何 rake 并运行 db:migrate 任务。

【讨论】:

以上是关于bundle exec rake 是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章

Rails--bundle exec rake db:migrate

bundle exec rake assets:预编译失败,出现“意外令牌”

在 bundle exec rake assets:precompile 后 OpsWorks 部署失败

$ bundle exec rake db:reset 命令提升无法删除 db/development.sqlite3

Github 操作工作流 PG::ConnectionBad:无法连接到服务器:运行 bundle exec rake 时没有这样的文件或目录

gitlab迁移版本不一致问题