RVM和rbenv如何工作? [英] How do RVM and rbenv actually work?

查看:129
本文介绍了RVM和rbenv如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



很明显,他们在不同版本的Ruby和gemsets之间进行了切换,但是它是如何实现的?我曾假设他们只是更新符号链接,但已经钻研了代码(我必须承认我对Bash的知识是肤浅的),但他们似乎做的不仅仅是这些。

简短解释:rbenv通过连接到你的环境的 PATH 来工作。这个概念很简单,但魔鬼在细节中;首先,rbenv为所有命令( ruby​​ )创建 shims irb rake gem 等)所有你安装的Ruby版本。这个过程被称为 rehashing 。每次安装新版本的Ruby或安装提供命令的gem时,请运行 rbenv rehash 以确保任何新命令都已被刷新。



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

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

然后任何时候从命令行运行 ruby​​ ,或者运行一个脚本,其脚本的内容是#!/ usr / bin / env ruby​​ ,你的操作系统首先会找到〜/ .rbenv / shims / ruby​​ ,然后运行它而不是任何其他的 ruby​​ 可执行文件,您可能已经安装了。



每个填充程序都是一个很小的Bash脚本,它依次运行 rbenv exec 。因此,在你的路径中使用rbenv, irb 相当于 rbenv exec irb ruby​​ - eputs 42相当于 rbenv exec ruby​​ -eputs 42



rbenv exec 命令会指出您要使用的Ruby版本,然后为该版本运行相应的命令。这是如何操作的:


  1. 如果设置了 RBENV_VERSION 环境变量,如果当前工作目录有 .rbenv-version 文件,则其内容用于设置 RBENV_VERSION 环境变量。

  2. 如果没有 .rbenv-version 文件在当前目录中,rbenv会在每个父目录中搜索 .rbenv-version 文件,直到它到达文件系统的根目录。如果找到一个,它的内容用于设置 RBENV_VERSION 环境变量。

  3. 如果 RBENV_VERSION
  4. code>仍未设置,rbenv尝试使用〜/ .rbenv / version 文件的内容进行设置。
  5. 如果没有在任何地方指定版本,rbenv会假定您想要使用系统Ruby-ie如果rbenv不在你的路径中,那么将运行任何版本。

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



使用> RBENV_VERSION 环境变量,rbenv将〜/ .rbenv / versions / $ RBENV_VERSION / bin 添加到你的 PATH ,然后执行传给 rbenv exec 的命令和参数。 Voila!



为了全面了解发生了什么,请尝试设置 RBENV_DEBUG = 1 并运行Ruby命令。 rbenv运行的每个Bash命令都会被写入您的终端。






现在rbenv只关注切换版本,但一个繁荣的插件生态系统将帮助您完成从安装Ruby 设置你的环境管理gemsets,甚至自动执行 bundle exec

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



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


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.

解决方案

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. 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.

这篇关于RVM和rbenv如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆