ruby RVM和rbenv实际上是如何工作的?

mznpcxlj  于 2023-04-29  发布在  Ruby
关注(0)|答案(5)|浏览(268)

我感兴趣的是RVM和rbenv实际上是如何工作的。
很明显,他们在不同版本的Ruby和gemset之间交换,但这是如何实现的呢?我原以为他们只是在更新符号链接,但在深入研究代码之后(我必须承认我对Bash的了解很肤浅),他们似乎做的不仅仅是这些。

mdfafbf1

mdfafbf11#

简短说明:rbenv通过连接到您环境的PATH来工作。概念简单,魔鬼却在细节;下面是满满一勺。
首先,rbenv为所有安装的Ruby版本中的所有命令(rubyirbrakegem等)创建 shims,也就是为~/.rbenv/versions/*/bin中的所有文件创建 * shims*。这个过程被称为“rehashing”。每次安装新版本的Ruby或安装提供命令的gem时,请运行rbenv rehash以确保所有新命令都被shimmed。
这些垫片位于单个目录中(默认情况下为~/.rbenv/shims)。要使用rbenv,你只需要在PATH的前面添加shims目录:

export PATH="$HOME/.rbenv/shims:$PATH"

然后,任何时候你从命令行运行ruby,或者运行一个脚本的脚本,其脚本的内容是#!/usr/bin/env ruby,你的操作系统都会首先找到~/.rbenv/shims/ruby并运行它,而不是你可能已经安装的任何其他ruby可执行文件。
每个shim都是一个小小的Bash脚本,它依次运行rbenv exec。因此,如果路径中有rbenv,则irb等效于rbenv exec irbruby -e "puts 42"等效于rbenv exec ruby -e "puts 42"
rbenv exec命令确定要使用哪个版本的Ruby,然后运行该版本的相应命令。具体操作如下:
1.如果设置了RBENV_VERSION环境变量,则其值决定了要使用的Ruby版本。
1.如果当前工作目录有.rbenv-version文件,则其内容用于设置RBENV_VERSION环境变量。
1.如果当前目录中没有.rbenv-version文件,rbenv会在每个父目录中搜索.rbenv-version文件,直到找到文件系统的根目录。如果找到一个,则使用其内容设置RBENV_VERSION环境变量。
1.如果RBENV_VERSION仍然没有设置,rbenv会尝试使用~/.rbenv/version文件的内容来设置它。
1.如果在任何地方都没有指定版本,rbenv假定您希望使用“系统”Ruby-i。即,如果rbenv不在您路径中,将运行的任何版本。
(You可以使用rbenv local命令设置特定于项目的Ruby版本,该命令在当前目录中创建.rbenv-version文件。类似地,rbenv global命令修改~/.rbenv/version文件。)
rbenv使用RBENV_VERSION环境变量,将~/.rbenv/versions/$RBENV_VERSION/bin添加到PATH的前面,然后执行传递给rbenv exec的命令和参数。瞧!
要彻底了解幕后到底发生了什么,请尝试设置RBENV_DEBUG=1并运行Ruby命令。rbenv运行的每个Bash命令都将写入您的终端。
现在,rbenv只关心切换版本,但一个蓬勃发展的插件生态系统将帮助您完成从installing Rubysetting up your environmentmanaging "gemsets"甚至automating bundle exec的所有操作。
我不太确定IRC支持与Ruby版本切换有什么关系,rbenv被设计得足够简单易懂,不需要支持。但是如果你需要帮助,问题跟踪器和Twitter只需要几次点击。

  • 信息披露:我是rbenv,ruby-build和rbenv-vars的作者。*
13z8s7eq

13z8s7eq2#

我写了一篇深度文章:http://niczsoft.com/2011/11/what-you-should-know-about-rbenv-and-rvm/
基本的区别在于shell环境的更改位置:

  • RVM:当你改变Ruby时,它会改变。
  • rbenv:当你运行Ruby/gem可执行文件时,它会改变。

此外,关于RVM的事情是,它涵盖了更多,然后只是管理Ruby,它比任何其他工具都多得多(除了RVM和rbenv之外还有其他工具:https://twitter.com/#!/mpapis/status/171714447910502401)
别忘了在Freenode服务器上的IRC“#rvm”频道中获得即时支持。

olqngx59

olqngx593#

所以总结一下以上优秀的答案,RVM和rbenv之间的主要实际区别在于Ruby版本的选择。

rbenv:

rbenv在路径的开头添加一个shim,这是一个与Ruby同名的命令。当你在命令行输入ruby时,shim会运行(因为它也被称为“ruby”,在路径中排在第一位)。shim会查找环境变量或.rbenv_version文件,以告诉它要委托给哪个版本的Ruby。

RVM:

RVM允许您通过调用rvm use直接设置Ruby的版本。此外,它还覆盖cd系统命令。当您将cd文件夹插入到包含.rvmrc文件的文件夹中时,将执行.rvmrc文件中的代码。这可以用来设置一个Ruby版本,或者任何你喜欢的东西。

其他差异:

当然还有其他的区别。RVM有开箱即用的gemsets,而rbenv只需要多一点黑客(但不多)。两者都是对问题的实用解决方案。

j5fpnvbx

j5fpnvbx4#

主要区别似乎是when and how ruby is switched。Ruby切换:

  • 对于RVM,手动(rvm使用)或在更改目录期间自动
  • for rbenv在每次执行ruby命令时自动执行

RVM依赖于修改后的cd命令和rvm use手动选择Ruby。rbenv对所有基本ruby命令使用wrappers或“shims”作为默认机制来选择ruby。RVM也为gem、rake、ruby等基本命令行工具创建 Package 器。例如,它们在CronJobs中使用(参见http://rvm.io/integration/cron/),但它们不是切换Ruby版本的默认机制。
因此,这两种方法都通过覆盖命令和使用 Package 器来“自动”选择正确的Ruby版本。rvm会覆盖像cd这样的shell命令。rbenv覆盖所有基本的ruby命令,如ruby、irb、rake和gem。

q0qdq0h2

q0qdq0h25#

rvm system
env > before
rvm jruby # or whatever
env > after
diff after before

给你大约:

< GEM_HOME=$HOME/.gem/ruby/1.9.1
---
> GEM_HOME=$HOME/.rvm/gems/jruby-1.6.6
< GEM_PATH=$HOME/.gem/ruby/1.9.1
---
> GEM_PATH=$HOME/.rvm/gems/jruby-1.6.6:$HOME/.rvm/gems/jruby-1.6.6@global
*bunch of rvm_*
> MY_RUBY_HOME=$HOME/.rvm/rubies/jruby-1.6.6
> RUBY_VERSION=jruby-1.6.6
> IRBRC=$HOME/.rvm/rubies/jruby-1.6.6/.irbrc

它预先说明:

$HOME/.rvm/gems/jruby-1.6.6/bin:$HOME/.rvm/gems/jruby-1.6.6@global/bin

$PATH

相关问题