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

发布于 2025-01-07 14:53:58 字数 146 浏览 0 评论 0原文

我对 RVM 和 rbenv 的实际工作原理感兴趣。

显然,它们在不同版本的 Ruby 和 gemset 之间进行交换,但这是如何实现的呢?我原以为他们只是简单地更新符号链接,但深入研究代码后(我必须承认我对 Bash 的了解很肤浅),他们似乎做的不仅仅是这些。

I am interested in how RVM and rbenv actually work.

Obviously they swap between different versions of Ruby and gemsets, but how is this achieved? I had assumed they were simply updating symlinks, but having delved into the code (and I must admit my knowledge of Bash is superficial) they appear to be doing more than this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

腻橙味 2025-01-14 14:53:59
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

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

Gives you approximately:

< 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

And it prepends:

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

to $PATH

天涯沦落人 2025-01-14 14:53:58

简短说明:rbenv 通过挂钩到您的环境的 PATH 来工作。概念很简单,但细节决定成败;下面是完整的勺子。

首先,rbenv 为所有命令(rubyirbrakegem 创建 shims code> 等)在所有已安装的 Ruby 版本中,即 ~/.rbenv/versions/*/bin 中的所有文件。这个过程称为重新哈希。每次安装新版本的 Ruby 或安装提供命令的 gem 时,请运行 rbenv rehash 来确保所有新命令均已填充。

这些垫片位于单个目录中(默认情况下为~/.rbenv/shims)。要使用 rbenv,您只需将 shims 目录添加到 PATH 的前面:

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

然后,每当您从命令行运行 ruby 时,或者运行 shebang 读取的脚本时, #!/usr/bin/env ruby​​,您的操作系统将首先找到 ~/.rbenv/shims/ruby 并运行它,而不是任何其他 ruby< /code> 您可能已安装的可执行文件。

每个 shim 都是一个微小的 Bash 脚本,依次运行 rbenv exec 。因此,当路径中包含 rbenv 时,irb 相当于 rbenv exec irb,而 ruby -e "puts 42" 相当于 rbenv exec ruby​​ -e "puts 42"

rbenv exec 命令确定您要使用的 Ruby 版本,然后运行该版本的相应命令。操作方法如下:

  1. 如果设置了 RBENV_VERSION 环境变量,则其值决定要使用的 Ruby 版本。
  2. 如果当前工作目录有 .rbenv-version 文件,则其内容用于设置 RBENV_VERSION 环境变量。
  3. 如果当前目录中没有 .rbenv-version 文件,rbenv 会在每个父目录中搜索 .rbenv-version 文件,直到它到达文件系统的根目录。如果找到,其内容将用于设置 RBENV_VERSION 环境变量。
  4. 如果 RBENV_VERSION 仍未设置,rbenv 会尝试使用 ~/.rbenv/version 文件的内容进行设置。
  5. 如果没有在任何地方指定版本,rbenv 假定您想要使用“系统”Ruby,即如果 rbenv 不在您的路径中,则运行任何版本。

(您可以使用 rbenv local 命令设置项目特定的 Ruby 版本,该命令会在当前目录中创建一个 .rbenv-version 文件。同样,rbenv global 命令修改 ~/.rbenv/version 文件。)

配备了 RBENV_VERSION 环境变量,rbenv 添加了将 ~/.rbenv/versions/$RBENV_VERSION/bin 添加到 PATH 的前面,然后执行传递给 rbenv exec 的命令和参数。瞧!

要彻底了解幕后发生的情况,请尝试设置 RBENV_DEBUG=1 并运行 Ruby 命令。 rbenv 运行的每个 Bash 命令都将写入您的终端。


现在,rbenv 只关心切换版本,但蓬勃发展的插件生态系统将帮助您完成从安装 Ruby 开始的所有事情设置您的环境管理“宝石集” 甚至 自动化捆绑执行

我不太确定 IRC 支持与切换 Ruby 版本有什么关系,而 rbenv 的设计足够简单易懂,不需要支持。但如果您需要帮助,只需点击几下即可访问问题跟踪器和 Twitter。

披露:我是 rbenv、ruby-build 和 rbenv-vars 的作者。

Short explanation: rbenv works by hooking into your environment's PATH. The concept is simple, but the devil is in the details; full scoop below.

First, rbenv creates shims for all the commands (ruby, irb, rake, gem and so on) across all your installed versions of Ruby, that is for all files in ~/.rbenv/versions/*/bin. This process is called rehashing. Every time you install a new version of Ruby or install a gem that provides a command, run rbenv rehash to make sure any new commands are shimmed.

These shims live in a single directory (~/.rbenv/shims by default). To use rbenv, you need only add the shims directory to the front of your PATH:

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

Then any time you run ruby from the command line, or run a script whose shebang reads #!/usr/bin/env ruby, your operating system will find ~/.rbenv/shims/ruby first and run it instead of any other ruby executable you may have installed.

Each shim is a tiny Bash script that in turn runs rbenv exec. So with rbenv in your path, irb is equivalent to rbenv exec irb, and ruby -e "puts 42" is equivalent to rbenv exec ruby -e "puts 42".

The rbenv exec command figures out what version of Ruby you want to use, then runs the corresponding command for that version. Here's how:

  1. If the RBENV_VERSION environment variable is set, its value determines the version of Ruby to use.
  2. If the current working directory has an .rbenv-version file, its contents are used to set the RBENV_VERSION environment variable.
  3. If there is no .rbenv-version file in the current directory, rbenv searches each parent directory for an .rbenv-version file until it hits the root of your filesystem. If one is found, its contents are used to set the RBENV_VERSION environment variable.
  4. If RBENV_VERSION is still not set, rbenv tries to set it using the contents of the ~/.rbenv/version file.
  5. If no version is specified anywhere, rbenv assumes you want to use the "system" Ruby—i.e. whatever version would be run if rbenv weren't in your path.

(You can set a project-specific Ruby version with the rbenv local command, which creates a .rbenv-version file in the current directory. Similarly, the rbenv global command modifies the ~/.rbenv/version file.)

Armed with an RBENV_VERSION environment variable, rbenv adds ~/.rbenv/versions/$RBENV_VERSION/bin to the front of your PATH, then execs the command and arguments passed to rbenv exec. Voila!

For a thorough look at exactly what happens under the hood, try setting RBENV_DEBUG=1 and running a Ruby command. Every Bash command that rbenv runs will be written to your terminal.


Now, rbenv is just concerned with switching versions, but a thriving ecosystem of plugins will help you do everything from installing Ruby to setting up your environment, managing "gemsets" and even automating bundle exec.

I am not quite sure what IRC support has to do with switching Ruby versions, and rbenv is designed to be simple and understandable enough not to require support. But should you ever need help, the issue tracker and Twitter are just a couple of clicks away.

Disclosure: I am the author of rbenv, ruby-build, and rbenv-vars.

梦情居士 2025-01-14 14:53:58

我写了一篇深入的文章:http://niczsoft.com /2011/11/what-you-should-know-about-rbenv-and-rvm/

基本区别在于 shell 环境发生了更改:

  • RVM:当您更改 Ruby 时,它也会更改。
  • rbenv:当您运行 Ruby/gem 可执行文件时,它会发生变化。

另外,关于 RVM 的一点是,它涵盖的内容不仅仅是管理 Rubies,它比任何其他工具都多得多(除了 RVM 和 rbenv 之外还有其他工具:https://twitter.com/#!/mpapis/status/171714447910502401

不要忘记您获得的即时支持在 Freenode 服务器上的“#rvm”频道中的 IRC 上。

I wrote an in-depth article: http://niczsoft.com/2011/11/what-you-should-know-about-rbenv-and-rvm/

The basic difference is where the shell environment is changed:

  • RVM: it's changed when you change Ruby.
  • rbenv: it's changed when you run a Ruby/gem executable.

Also, the thing about RVM is, it covers a lot more then just managing Rubies, it has a lot more than any other tool (there are others apart from RVM and rbenv: https://twitter.com/#!/mpapis/status/171714447910502401)

Do not forget about instant support you get on IRC in the "#rvm" channel on the Freenode servers.

怎言笑 2025-01-14 14:53:58

因此,总结上面的优秀答案,RVM 和 rbenv 之间的主要实际区别在于选择 Ruby 版本的时间。

rbenv:

rbenv 在路径的开头添加一个填充程序,这是一个与 Ruby 同名的命令。当您在命令行中键入 ruby​​ 时,将运行填充程序(因为它也称为“ruby”并且位于路径的第一位)。填充程序会查找环境变量或 .rbenv_version 文件来告诉它要委托给哪个版本的 Ruby。

RVM:

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

其他差异:

当然还有其他差异。 RVM 具有开箱即用的 gemset,而 rbenv 只需要更多一点的修改(但不多)。两者都是问题的实用解决方案。

So to summarise the excellent answers above, the main practical difference between RVM and rbenv is when the version of Ruby is selected.

rbenv:

rbenv adds a shim to the start of your path, a command with the same name as Ruby. When you type ruby at a command line the shim is run instead (because it is also called "ruby" and comes first in the path). The shim looks for an environment variable or .rbenv_version file to tell it which version of Ruby to delegate to.

RVM:

RVM allows you to set a version of Ruby directly by calling rvm use. In addition, it also overrides the cd system command. When you cd into a folder that contains a .rvmrc file, the code inside the .rvmrc file is executed. This can be used to set a Ruby version, or anything else you fancy.

Other differences:

There are of course other differences. RVM has gemsets out of the box, while rbenv requires just a little more hacking (but not much). Both are functional solutions to the problem.

三岁铭 2025-01-14 14:53:58

主要区别似乎是 何时以及如何切换 ruby​​。 Ruby 切换:

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

RVM 依赖于修改后的 cd 命令并通过 手动选择 Ruby rvm 使用。 rbenv 对所有基本 ruby​​ 命令使用包装器或“垫片”作为选择 ruby​​ 的默认机制。 RVM 还为基本命令行工具(如 gem、rake、ruby)创建包装器。例如,它们在 CronJobs 中使用(请参阅 http://rvm.io/integration/cron/ ),但它们不是切换 Ruby 版本的默认机制。

因此,这两种方法都通过覆盖命令和使用包装器“自动”选择正确的 Ruby 版本。 rvm 会覆盖 cd 等 shell 命令。 rbenv 覆盖所有基本的 ruby​​ 命令,例如 ruby​​、irb、rake 和 gem。

The main difference seems to be when and how ruby is switched. Ruby is switched:

  • for RVM manually (rvm use) or automatically during change of directories
  • for rbenv automatically each time a ruby command is executed

RVM relies on the modified cd command and manual selection of Ruby by rvm use. rbenv uses wrappers or "shims" for all basic ruby commands as the default mechanism to select ruby. RVM creates wrappers for basic command line tools like gem, rake, ruby, too. They are used for example in CronJobs ( see http://rvm.io/integration/cron/ ), but they are not the default mechanism to switch the Ruby version.

Thus both methods select "automatically" the right Ruby version by overwriting commands and using wrappers. rvm overrides shell commands like cd. rbenv overrides all basic ruby commands such as ruby, irb, rake and gem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文