bundle exec rake db:migrate
是什么意思?或者只是bundle exec rake <command>
?
我理解bundle
负责维护Gemfile中的内容。我知道“exec”这个词是什么意思。我理解rake
维护了你可以做的所有不同的脚本事情,我知道db:migrate
就是其中之一。我只是不知道这些话在一起做什么。为什么bundle
用于执行rake
执行数据库迁移?
答案 0 :(得分:443)
bundle exec
是一个Bundler命令,用于在当前包(您目录的Gemfile中的一个)的上下文中执行脚本。 rake db:migrate
是 db 是命名空间的脚本, migrate 是定义的任务名称。
所以bundle exec rake db:migrate
在当前包的上下文中使用命令db:migrate
执行rake脚本。
至于“为什么?”我将引用bundler page:
在某些情况下,如果可执行文件恰好安装在您的系统中并且没有引入任何与您的软件包冲突的宝石,那么运行不带
bundle exec
的可执行文件可能会有效。然而,这是不可靠的,并且是相当痛苦的根源。即使它看起来有效,但它可能在将来或其他机器上不起作用。
答案 1 :(得分:142)
您正在程序上运行bundle exec
。该程序的创建者在某些版本的宝石可用时编写了它。程序Gemfile指定创建者决定使用的gem的版本。也就是说,脚本可以针对这些gem版本正确运行。
您的系统级Gemfile可能与此Gemfile不同。你可能有更新或更旧的宝石,这个脚本不能很好地运行。这种版本差异可以给你带来奇怪的错误。
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执行脚本,而不是您可能在系统范围内安装的其他版本。
答案 2 :(得分:7)
当你的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
然后尝试你的佣金,rspec或其他任何东西。
答案 3 :(得分:6)
应该提到的是,有些方法可以省略bundle exec
(这些都在迈克尔·哈特斯{3.6}的第3.6.1章中有所说明)。
最简单的方法是使用足够最新版本的RVM(&gt; = 1.11.x)。
如果您仅限于早期版本的RVM,则可以始终使用Ruby on Rails Tutorial提到的此方法:
$ 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
答案 4 :(得分:1)
我没有使用bundle exec,但我现在正在设置它。
我遇到了使用错误的rake的情况,浪费了大量时间来追踪问题。这可以帮助您避免这种情况。
以下是设置rvm的方法,以便您可以在特定项目目录中默认使用bundle exec:
http://robots.thoughtbot.com/post/15346721484/use-bundlers-binstubs
答案 5 :(得分:1)
直接运行rake任务或执行gem的任何二进制文件时,无法保证命令的行为符合预期。因为您可能已经在系统上安装了相同的gem,其版本为1.0,但在您的项目中,您的版本更高,即2.0。在这种情况下,您无法预测将使用哪一个。
要强制执行所需的gem版本,您需要bundle exec
命令的帮助,该命令将在当前bundle的上下文中执行二进制文件。这意味着当您使用bundle exec时,bundler会检查为当前项目配置的gem版本,并使用它来执行任务。
我还写了一篇关于它的post,它也说明了我们如何避免使用bin存根来使用它。
答案 6 :(得分:0)
这意味着使用捆绑器知道的rake,并且是捆绑器不知道的任何rake的Gemfile的一部分,并运行db:migrate任务。