ChatGPT解决这个技术问题 Extra ChatGPT

bundle exec rake 是什么意思?

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

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


O
Onato

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

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

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

在某些情况下,如果可执行文件恰好安装在您的系统中并且没有拉入任何与您的捆绑包冲突的 gem,则在没有 bundle exec 的情况下运行可执行文件可能会起作用。然而,这是不可靠的并且是相当大的痛苦的来源。即使它看起来可以正常工作,但将来或在另一台机器上可能无法正常工作。


这是否意味着我们应该始终运行 bundle exec,我使用 ruby 版本管理器在 rails 上安装 ruby 和 ruby。
@Edmund“捆绑”是一个英文单词,意思是一组相似的东西,通常整齐地捆绑在一起。具体在这个问题中,它指的是一组 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 安装一样。他们也可以选择较短的版本作为使用频率更高的版本(本地版本)。
J
Jake Worth

您正在一个程序上运行 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_gem,则 bundle 使用“特定于机器”的全局 gem。本地与全球
比选择的答案要好得多。
B
Benjamin Dunphy

当您的 gemfile.lock 在您的机器上安装了不同版本的 gems 时,这会出现很多。运行 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 年仍然是一个很好的解决方案。
C
Community

可能应该提到,有一些方法可以省略 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

A
Ajit Singh

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

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

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


D
Dave Powers

bundle exec 我用的不多,但现在正在设置它。

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

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

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


O
Omar Qureshi

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