bundle exec rake db:migrate 是什么意思?或者只是 bundle exec rake <command> 一般?
bundle exec rake db:migrate
bundle exec rake <command>
我知道 bundle 负责维护Gemfile中的内容 . 我知道"exec"这个词是什么意思 . 我知道 rake 维护着你可以做的所有不同的脚本事情,我知道 db:migrate 就是其中之一 . 我只是不知道这些话在一起做什么 . 为什么 bundle 用于执行 rake 来执行数据库迁移?
bundle
rake
db:migrate
bundle exec是一个Bundler命令,用于在当前包的上下文中执行脚本(来自目录的Gemfile) . rake db:migrate 是db是命名空间的脚本,migrate是定义的任务名称 .
rake db:migrate
所以 bundle exec rake db:migrate 在当前包的上下文中使用命令 db:migrate 执行rake脚本 .
至于"why?"我会引用bundler page:
在某些情况下,如果可执行文件恰好安装在您的系统中并且不会引入任何与您的软件包冲突的gem,则运行不带bundle exec的可执行文件可能会有效 . 然而,这是不可靠的,并且是相当痛苦的根源 . 即使看起来它有效,它可能在将来或在另一台机器上不起作用 .
你在程序上运行 bundle exec . 该程序的创建者在某些版本的宝石可用时编写了它 . 程序Gemfile指定创建者决定使用的gem的版本 . 也就是说,脚本可以针对这些gem版本正确运行 .
bundle exec
您的系统范围的Gemfile可能与此Gemfile不同 . 你可能有更新或更旧的宝石,这个脚本不能很好地运行 . 版本的这种差异可以给你带来奇怪的错误 .
Bundle exec 可以帮助您避免这些错误 . 它使用脚本的Gemfile中指定的gem而不是系统范围的Gemfile来执行脚本 . 它使用shell别名的魔力执行某些gem版本 .
Bundle exec
在the man page上查看更多信息 .
这是Gemfile的一个例子:
source 'http://rubygems.org' gem 'rails', '2.8.3'
在这里, bundle exec 将使用rails版本2.8.3执行脚本,而不是您可能已在系统范围内安装的其他版本 .
当你的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或其他任何东西 .
应该提到的是,有些方法可以省略 bundle exec (这些都在Michael Hartls的第3.6.1章Ruby on Rails Tutorial书中有所说明) .
最简单的方法是使用足够最新版本的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
我没有太多使用bundle exec,但我现在正在设置它 .
我有过使用错误的rake的情况,浪费了很多时间来追踪问题 . 这有助于您避免这种情况 .
以下是设置rvm的方法,以便您可以在特定项目目录中默认使用bundle exec:
http://robots.thoughtbot.com/post/15346721484/use-bundlers-binstubs
直接运行rake任务或执行gem的任何二进制文件时,无法保证命令的行为符合预期 . 因为您可能已经在系统上安装了相同的gem,其版本为1.0,但在您的项目中,您的版本更高,即2.0 . 在这种情况下,您无法预测将使用哪一个 .
要强制执行所需的gem版本,请使用 bundle exec 命令的帮助,该命令将在当前bundle的上下文中执行二进制文件 . 这意味着当您使用bundle exec时,bundler会检查为当前项目配置的gem版本并使用它来执行该任务 .
我还写了一篇关于它的文章,它也显示了我们如何避免使用bin存根来使用它 .
它意味着使用捆绑器知道的rake,并且是捆绑器不知道的任何rake的Gemfile的一部分,并运行db:migrate任务 .
7 回答
bundle exec是一个Bundler命令,用于在当前包的上下文中执行脚本(来自目录的Gemfile) .
rake db:migrate
是db是命名空间的脚本,migrate是定义的任务名称 .所以
bundle exec rake db:migrate
在当前包的上下文中使用命令db:migrate
执行rake脚本 .至于"why?"我会引用bundler page:
你在程序上运行
bundle exec
. 该程序的创建者在某些版本的宝石可用时编写了它 . 程序Gemfile指定创建者决定使用的gem的版本 . 也就是说,脚本可以针对这些gem版本正确运行 .您的系统范围的Gemfile可能与此Gemfile不同 . 你可能有更新或更旧的宝石,这个脚本不能很好地运行 . 版本的这种差异可以给你带来奇怪的错误 .
Bundle exec
可以帮助您避免这些错误 . 它使用脚本的Gemfile中指定的gem而不是系统范围的Gemfile来执行脚本 . 它使用shell别名的魔力执行某些gem版本 .在the man page上查看更多信息 .
这是Gemfile的一个例子:
在这里,
bundle exec
将使用rails版本2.8.3执行脚本,而不是您可能已在系统范围内安装的其他版本 .当你的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或其他任何东西 .
应该提到的是,有些方法可以省略
bundle exec
(这些都在Michael Hartls的第3.6.1章Ruby on Rails Tutorial书中有所说明) .最简单的方法是使用足够最新版本的RVM(> = 1.11.x) .
如果您被限制为早期版本的RVM,则始终可以使用calasyr也提到的此方法:
然后还应将
bundler_stubs
目录添加到.gitignore
文件中 .如果您不使用RVM,第三个选项是使用
rubygems-bundler
gem:我没有太多使用bundle exec,但我现在正在设置它 .
我有过使用错误的rake的情况,浪费了很多时间来追踪问题 . 这有助于您避免这种情况 .
以下是设置rvm的方法,以便您可以在特定项目目录中默认使用bundle exec:
http://robots.thoughtbot.com/post/15346721484/use-bundlers-binstubs
直接运行rake任务或执行gem的任何二进制文件时,无法保证命令的行为符合预期 . 因为您可能已经在系统上安装了相同的gem,其版本为1.0,但在您的项目中,您的版本更高,即2.0 . 在这种情况下,您无法预测将使用哪一个 .
要强制执行所需的gem版本,请使用
bundle exec
命令的帮助,该命令将在当前bundle的上下文中执行二进制文件 . 这意味着当您使用bundle exec时,bundler会检查为当前项目配置的gem版本并使用它来执行该任务 .我还写了一篇关于它的文章,它也显示了我们如何避免使用bin存根来使用它 .
它意味着使用捆绑器知道的rake,并且是捆绑器不知道的任何rake的Gemfile的一部分,并运行db:migrate任务 .