Answers:
bundle exec
是一个Bundler命令,用于在当前分发包(目录中Gemfile中的那个)的上下文中执行脚本。rake db:migrate
是脚本,其中db是名称空间,而migration是定义的任务名称。
因此,在当前包的上下文中bundle exec rake db:migrate
使用命令执行rake脚本db:migrate
。
至于“为什么?” 我将在捆绑器页面中引用:
在某些情况下,
bundle exec
如果该可执行文件恰好安装在您的系统中并且不会拉入任何与您的软件包冲突的gem,则运行不带可执行文件的可执行文件可能会起作用。然而,这是不可靠的并且是相当大痛苦的根源。即使看起来可以使用,将来也可能无法在另一台计算机上使用。
.ruby-gemset
在项目根目录中有文件时才为真。.ruby-version
如果使用RVM,还有一个文件可以设置您的ruby版本。
您正在运行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版而不是您可能已在系统范围内安装的其他版本来执行脚本。
rake db:migrate
了出去,bundle exec
那么它将使用系统范围内的Gemfile执行该文件,其中某个文件可能位于1.5.2(最新)?
bundle exec
在应用程序的Gemfile中使用“特定于应用程序”的本地gem,如果bundle
使用,则使用“特定于计算机”的全局gem gem install a_certain_gem
。本地与全球
当您的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或其他方法。
应该提到的是,有一些方法可以忽略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
当您直接运行rake任务或执行gem的任何二进制文件时,无法保证该命令的行为符合预期。因为可能会发生,您的系统上已经安装了相同的gem,版本为1.0,但是在您的项目中,您的版本为2.0。在这种情况下,您无法预测将使用哪一个。
要强制执行所需的gem版本,请使用bundle exec
命令的帮助,该命令将在当前包的上下文中执行二进制文件。这意味着当您使用bundle exec时,bundler会检查为当前项目配置的gem版本,并使用它来执行任务。
我也写了一篇有关它的文章,它还显示了如何避免使用bin存根使用它。
我没有用bundle exec
太多,但是现在进行设置。
我曾经遇到过使用错误的耙子的情况,并且浪费大量时间来查找问题。这可以帮助您避免这种情况。
设置RVM的方法如下,以便bundle exec
默认情况下可以在特定项目目录中使用:
这意味着使用捆绑程序可以识别的耙,并且比捆绑程序不知道的任何耙都属于您的Gemfile,并运行db:migrate任务。