RVM과 rbenv는 실제로 어떻게 작동합니까?


140

RVM과 rbenv의 실제 작동 방식에 관심이 있습니다.

분명히 그들은 서로 다른 버전의 루비와 젬셋 사이를 교환하지만 어떻게 달성됩니까? 나는 그들이 단순히 심볼릭 링크를 업데이트한다고 가정했지만 코드를 파헤 쳤고 (Bash에 대한 나의 지식이 피상적이라는 것을 인정해야 함) 그들은 이것보다 더 많은 일을하는 것으로 보입니다.

답변:


241

간단한 설명 : rbenv는 환경에 연결하여 작동합니다 PATH. 개념은 간단하지만 악마는 세부 사항에 있습니다. 아래에 전체 국자.

첫째, rbenv가 생성 모든 명령에 대한을 ( ruby, irb, rake, gem등) 루비의 설치된 모든 버전에서. 이 과정을 리 해싱 이라고 합니다. 새로운 버전의 Ruby를 설치하거나 명령을 제공하는 gem을 설치할 때마다 rbenv rehash새로운 명령이 지워지도록 실행 하십시오.

이 심은 단일 디렉토리에 있습니다 ( ~/.rbenv/shims기본적으로). rbenv를 사용하려면 shim 디렉토리를 다음의 앞에 추가하면됩니다 PATH.

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

그런 다음 ruby명령 행에서 실행하거나 shebang이 읽은 스크립트를 실행하면 #!/usr/bin/env ruby운영 체제가 ~/.rbenv/shims/ruby먼저 ruby설치 한 다른 실행 파일 대신 이를 찾아 실행합니다.

각 심은 차례로 실행되는 작은 Bash 스크립트입니다 rbenv exec. 따라서 경로에 rbenv가 있으면 irb에 해당 rbenv exec irb하고 ruby -e "puts 42"에 해당합니다 rbenv exec ruby -e "puts 42".

rbenv exec명령은 사용하려는 Ruby 버전을 확인한 다음 해당 버전에 해당하는 명령을 실행합니다. 방법은 다음과 같습니다.

  1. 경우] RBENV_VERSION환경 변수를 설정하고, 그 값을 사용 루비의 버전을 판단한다.
  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=1Ruby 명령을 설정 하고 실행하십시오. rbenv가 실행하는 모든 Bash 명령이 터미널에 작성됩니다.


이제 rbenv 단지 전환 버전과 관련되어 있지만, 플러그인의 번성 생태계는 모든 것을 할 도움이 될 것입니다 루비를 설치환경을 설정 , "gemsets"를 관리 하고 심지어 자동화bundle exec .

IRC 지원이 Ruby 버전 전환과 어떤 관련이 있는지 잘 모르겠으며 rbenv는 지원이 필요하지 않을 정도로 단순하고 이해할 수 있도록 설계되었습니다. 그러나 도움이 필요하면 이슈 트래커와 트위터를 몇 번만 클릭하면됩니다.

공개 : 저는 rbenv, ruby-build 및 rbenv-vars의 저자입니다.


14
훌륭한 답변을 해주셔서 감사합니다.
superluminary

2
와, 이해하기 쉽고 이해하기 쉬운 설명 감사합니다. 타고난 선생.
racl101

이봐, 샘,이 대답은 2 살이 기 때문에 업데이트를 원하십니까? 그 이후로 rbenv에서 무언가가 바뀌 었습니다.
Nakilon

아니. 내가 본 최고의 해커의 설명. 나는 거기에서 변경해야 할 유일한 업데이트는 rbenv-gemset에 대한 링크에 있다고 생각합니다.
Jeffrey 'jf'Lim

18

나는 심층 기사를 썼습니다 : http://niczsoft.com/2011/11/what-you-should-know-about-rbenv-and-rvm/

기본적인 차이점은 쉘 환경이 변경되는 위치입니다.

  • RVM : Ruby를 변경하면 변경됩니다.
  • rbenv : Ruby / gem 실행 파일을 실행할 때 변경됩니다.

또한 RVM에 관한 것은 루비를 관리하는 것보다 훨씬 더 많은 것을 다루고 있으며 다른 도구보다 훨씬 많은 도구가 있습니다 (RVM 및 rbenv와 다른 도구가 있습니다 : https://twitter.com/#!/mpapis/ 상태 / 171714447910502401 )

Freenode 서버의 "#rvm"채널에서 IRC에 대한 즉각적인 지원을 잊지 마십시오.


1
감사합니다. 두 커뮤니티의 사람들이 참여하는 것이 정말 좋습니다.
superluminary

15

위의 훌륭한 답변을 요약하면 RVM과 rbenv의 주요 실제 차이점은 Ruby 버전을 선택할 때입니다.

rbenv :

rbenv는 경로 시작 부분에 Ruby와 동일한 이름을 가진 shim을 추가합니다. 당신은 입력하면 ruby(그것은 또한 "루비"라고하며 경로에 먼저 때문에) 심 대신에 실행되는 명령 줄에서. shim은 환경 변수 또는 .rbenv_version파일을 찾아 어떤 버전의 Ruby를 위임할지 알려줍니다.

RVM :

RVM을 사용하면을 호출하여 Ruby 버전을 직접 설정할 수 있습니다 rvm use. 또한 cd시스템 명령 도 무시합니다 . 때를 cd이 들어있는 폴더에 .rvmrc파일을 내부 코드 .rvmrc파일이 실행됩니다. 루비 버전이나 다른 멋진 것을 설정하는 데 사용할 수 있습니다.

다른 차이점들 :

물론 다른 차이점이 있습니다. RVM은 기본적으로 보석 세트를 가지고 있지만 rbenv는 약간의 해킹이 더 필요합니다. 둘 다 문제에 대한 기능적 솔루션입니다.


6

주요 차이점은 루비가 언제 어떻게 전환 되는가 에있다 . 루비가 바뀐다 :

  • RVM 수동 (rvm 사용) 또는 디렉토리 변경 중 자동
  • 루비 명령이 실행될 때마다 자동으로 rbenv

RVM은 수정 된 cd명령 및 Ruby by의 수동 선택에 의존합니다 rvm use. rbenv는 루비를 선택하는 기본 메커니즘으로 모든 기본 루비 명령에 래퍼 또는 "shims"를 사용합니다. RVM은 gem, rake, ruby와 같은 기본 명령 줄 도구를위한 래퍼도 만듭니다. 예를 들어 CronJobs ( http://rvm.io/integration/cron/ 참조 )에서 사용되지만 Ruby 버전을 전환하는 기본 메커니즘은 아닙니다.

따라서 두 방법 모두 명령을 덮어 쓰고 래퍼를 사용하여 올바른 Ruby 버전을 "자동으로"선택합니다. rvm은 cd와 같은 쉘 명령을 대체합니다. rbenv는 ruby, irb, rake 및 gem과 같은 모든 기본 ruby ​​명령을 무시합니다.


5
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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.