Bundle exec rake是什么意思?


350

什么bundle exec rake db:migrate意思 还是bundle exec rake <command>一般而言?

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

Answers:


468

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

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

至于“为什么?” 我将在捆绑器页面中引用:

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

然而,这是不可靠的并且是相当大痛苦的根源。即使看起来可以使用,将来也可能无法在另一台计算机上使用。


7
这是否意味着我们应该始终运行bundle exec,我已经使用ruby版本管理器在ruby上安装ruby和ruby了。
Pradeep Sharma 2012年

11
@Edmund“ bundle”是一个英文单词,意思是一组类似的东西,通常绑得整整齐齐。特别是在这个问题中,它涉及一组Gems(自包含的红宝石代码库)。Bundler是我们在这里用来管理Gems的软件的名称。并且bundle是用于由捆扎机的命令。
ghoppe

2
我的印象是,只要我们CD到带有Gemfile的文件夹,外壳程序都会自动使用Gemfile中指定的版本(例如Ruby版本)。基于这个假设,我认为不用dbm exec就可以使rake db:migrate正常运行。CMIIW
Pahlevi Fikri Auliya 2014年

1
@PahleviFikriAuliya仅.ruby-gemset在项目根目录中有文件时才为真。.ruby-version如果使用RVM,还有一个文件可以设置您的ruby版本。
fish鱼2015年

1
链接页面不再提及您指定的报价。请修复,谢谢。
朗丹东(Gaurang Tandon)'18年

153

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

您系统范围的Gemfile可能与此Gemfile不同。您可能拥有较新或较旧的gem,但此脚本无法很好地发挥作用。版本上的这种差异可能会给您带来怪异的错误。

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

有关更多信息,请参见手册页

这是一个示例Gemfile:

source 'http://rubygems.org'

gem 'rails', '2.8.3'

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


9
我比OP:D更喜欢这个答案!更清晰。
mauricioschneider 2013年

1
因此,要添加到此示例中:如果该人只是简单地跑rake db:migrate了出去,bundle exec那么它将使用系统范围内的Gemfile执行该文件,其中某个文件可能位于1.5.2(最新)?
Smokin Joe 2014年

结合具体示例,更好的答案。
ahnbizcad 2015年

2
因此,请bundle exec在应用程序的Gemfile中使用“特定于应用程序”的本地gem,如果bundle使用,则使用“特定于计算机”的全局gem gem install a_certain_gem。本地与全球
ahnbizcad

比选择的答案好得多。
Boon 2015年

9

当您的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告诉捆绑程序执行此命令,而不考虑版本差异。并不总是有问题,但是,您可能会遇到问题。

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

$ gem install rubygems-bundler

$ $ gem regenerate_binstubs

然后再尝试使用rake,rspec或其他方法。


在2020
。– Brateq

6

应该提到的是,有一些方法可以忽略bundle exec(它们全部在Michael Hartls Ruby on Rails教程的 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文件中。

第三种选择是rubygems-bundler在不使用RVM的情况下使用gem:

$ gem install rubygems-bundler
$ gem regenerate_binstubs

1

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

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

我也写了一篇有关它的文章,它还显示了如何避免使用bin存根使用它。


1

我没有用bundle exec太多,但是现在进行设置。

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

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

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


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.