bundle exec rake db:migrate是什么意思?或者只是一般的bundle exec rake <command> ?
bundle exec rake db:migrate
bundle exec rake <command>
我理解bundle负责维护Gemfile中的东西。我知道"执行"是什么意思。我知道rake维护了你可以做的所有不同的脚本事情,而且我知道db:migrate是其中之一。我只是不知道这些词在一起有什么用。为什么应该使用bundle来执行rake来执行数据库迁移?
bundle
rake
db:migrate
这意味着使用捆绑者知道的rake,它是您Gemfile的一部分,而不是捆绑者不知道的任何rake,并运行db:migrate任务。
bundle exec是一个打包机命令,用于在当前包的上下文中执行脚本(来自你目录的Gemfile)。rake db:migrate是脚本,其中db是命名空间,迁移是定义的任务名称。
bundle exec
rake db:migrate
因此,bundle exec rake db:migrate在当前bundle的上下文中使用命令db:migrate执行rake脚本。
至于“为什么?”我将引用打包机的页面:
在某些情况下,运行没有bundle exec的可执行文件可能会工作,如果可执行文件恰好安装在你的系统中,并且没有拉入任何与你的包冲突的gem。 然而,这是不可靠的,也是相当痛苦的来源。即使它看起来可以工作,但在将来或在另一台机器上可能无法工作。
在某些情况下,运行没有bundle exec的可执行文件可能会工作,如果可执行文件恰好安装在你的系统中,并且没有拉入任何与你的包冲突的gem。
然而,这是不可靠的,也是相当痛苦的来源。即使它看起来可以工作,但在将来或在另一台机器上可能无法工作。
我没有使用bundle exec太多,但现在正在设置它。
我曾经使用过错误的耙子,浪费了很多时间来追踪问题。这可以帮助你避免这种情况。
下面是如何设置RVM,这样你就可以在特定的项目目录中默认使用bundle exec:
https://thoughtbot.com/blog/use-bundlers-binstubs
你在一个程序上运行bundle exec。该程序的创建者在特定版本的宝石可用时编写它。Gemfile程序指定了创建者决定使用的gems的版本。也就是说,该脚本可以在这些gem版本上正确运行。
您的系统级Gemfile可能与此Gemfile不同。您可能有新的或旧的宝石,这个脚本不能很好地处理它们。版本之间的这种差异可能会导致奇怪的错误。
bundle exec帮助你避免这些错误。它使用脚本Gemfile中指定的gem执行脚本,而不是系统范围的Gemfile。它使用shell别名的魔力执行特定的gem版本。
参见手册页。
这是一个Gemfile的例子:
source 'http://rubygems.org' gem 'rails', '2.8.3'
在这里,bundle exec将使用rails 2.8.3版本执行脚本,而不是您可能在系统范围内安装的其他版本。
可能应该提到的是,有很多方法可以省略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文件中。
bundler_stubs
.gitignore
如果你不使用RVM,第三个选项是使用rubygems-bundler gem:
rubygems-bundler
$ gem install rubygems-bundler $ gem regenerate_binstubs
这在你的gemfile中经常出现。Lock在您的机器上安装了不同版本的宝石。在运行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,或者别的什么。
当您直接运行rake任务或执行gem的任何二进制文件时,不能保证该命令将按照预期的方式运行。因为可能发生的情况是,你的系统上已经安装了相同的gem,它的版本是1.0,但在你的项目中,你有更高的版本,比如2.0。在这种情况下,您无法预测将使用哪一个。
要强制执行想要的gem版本,可以使用bundle exec命令,该命令将在当前bundle的上下文中执行二进制文件。这意味着当您使用bundle exec时,bundler会检查为当前项目配置的gem版本,并使用该版本执行任务。
我还写了一个关于它的<强>文章< / >强,这也说明了我们如何使用bin存根来避免使用它。