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

2024-04-28

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

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


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

首先,rbenv 创建shims对于所有命令(ruby, irb, rake, gem等等)在所有已安装的 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您可能已经安装了可执行文件。

每个 shim 都是一个微小的 Bash 脚本,依次运行rbenv exec。所以在你的路径中使用 rbenv ,irb相当于rbenv exec irb, and ruby -e "puts 42"相当于rbenv exec ruby -e "puts 42".

The rbenv exec命令找出您要使用的 Ruby 版本,然后运行该版本的相应命令。就是这样:

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

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

武装有RBENV_VERSION环境变量,rbenv 添加~/.rbenv/versions/$RBENV_VERSION/bin到你的面前PATH,然后执行传递给的命令和参数rbenv exec. Voila!

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


现在,rbenv 只关心切换版本,但蓬勃发展的插件生态系统将帮助您完成从安装红宝石 https://github.com/sstephenson/ruby-build to 设置您的环境 https://github.com/sstephenson/rbenv-vars, 管理“宝石集” https://github.com/jamis/rbenv-gemset乃至自动化bundle exec https://github.com/carsomyr/rbenv-bundler.

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

RVM 和 rbenv 实际上是如何工作的? 的相关文章

随机推荐