2012-02-22 45 views
131

Tôi quan tâm đến cách RVM và rbenv thực sự hoạt động.RVM và rbenv thực sự hoạt động như thế nào?

Rõ ràng là chúng trao đổi giữa các phiên bản Ruby và đá quý khác nhau, nhưng làm cách nào để đạt được điều này? Tôi đã giả định rằng họ chỉ đơn giản cập nhật các liên kết tượng trưng, ​​nhưng đã bị đào sâu vào mã (và tôi phải thừa nhận kiến ​​thức của mình về Bash là bề ngoài) chúng dường như đang làm nhiều hơn thế.

Trả lời

225

Giải thích ngắn gọn: rbenv hoạt động bằng cách gắn vào môi trường PATH của môi trường của bạn. Khái niệm này rất đơn giản, nhưng ma quỷ ở trong các chi tiết; đầy đủ muỗng dưới đây.

Thứ nhất, rbenv tạo shims cho tất cả các lệnh (ruby, irb, rake, gem và vân vân) trên tất cả các phiên bản cài đặt của bạn của Ruby. Quá trình này được gọi là rehashing. Mỗi khi bạn cài đặt một phiên bản mới của Ruby hoặc cài đặt một gem cung cấp một lệnh, hãy chạy rbenv rehash để đảm bảo mọi lệnh mới được shimmed.

Các miếng chêm này sống trong một thư mục duy nhất (~/.rbenv/shims theo mặc định). Để sử dụng rbenv, bạn chỉ cần thêm thư mục miếng chêm vào phía trước của PATH của bạn:

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

Sau đó, bất cứ lúc nào bạn chạy ruby từ dòng lệnh, hoặc chạy một kịch bản mà công việc đọc #!/usr/bin/env ruby, hệ điều hành của bạn sẽ tìm thấy ~/.rbenv/shims/ruby trước tiên và chạy nó thay vì bất kỳ tệp thực thi ruby nào khác mà bạn có thể đã cài đặt.

Mỗi shim là một tập lệnh Bash nhỏ mà lần lượt chạy rbenv exec. Vì vậy, với rbenv trong đường dẫn của bạn, irb tương đương với rbenv exec irbruby -e "puts 42" tương đương với rbenv exec ruby -e "puts 42".

Lệnh rbenv exec chỉ ra phiên bản Ruby bạn muốn sử dụng, sau đó chạy lệnh tương ứng cho phiên bản đó. Đây là cách:

  1. Nếu biến RBENV_VERSION môi trường được thiết lập, giá trị của nó xác định phiên bản của Ruby để sử dụng.
  2. Nếu thư mục làm việc hiện tại có tệp .rbenv-version, nội dung của nó được sử dụng để đặt biến môi trường RBENV_VERSION.
  3. Nếu không có tệp .rbenv-version trong thư mục hiện tại, rbenv tìm kiếm mỗi thư mục mẹ cho một tệp .rbenv-version cho đến khi nó truy cập vào thư mục gốc của hệ thống tệp của bạn. Nếu tìm thấy, nội dung của nó được sử dụng để đặt biến môi trường RBENV_VERSION.
  4. Nếu RBENV_VERSION vẫn chưa được đặt, rbenv sẽ cố gắng đặt nó bằng nội dung của tệp ~/.rbenv/version.
  5. Nếu không có phiên bản nào được chỉ định ở bất kỳ đâu, rbenv giả sử bạn muốn sử dụng "hệ thống" Ruby — nghĩa là. bất kỳ phiên bản nào sẽ được chạy nếu rbenv không nằm trong đường dẫn của bạn.

(Bạn có thể đặt một phiên bản Ruby dự án cụ thể với rbenv local lệnh, mà tạo ra một tập tin .rbenv-version trong thư mục hiện hành. Tương tự như vậy, lệnh rbenv global đổi các tập tin ~/.rbenv/version.)

vũ trang với một RBENV_VERSION biến môi trường, rbenv thêm ~/.rbenv/versions/$RBENV_VERSION/bin vào mặt trước của PATH, sau đó thực thi lệnh và đối số được chuyển đến rbenv exec. Thì đấy!

Để tìm hiểu chính xác những gì xảy ra dưới mui xe, hãy thử đặt RBENV_DEBUG=1 và chạy lệnh Ruby. Mỗi lệnh Bash mà rbenv chạy sẽ được ghi vào terminal của bạn.


Bây giờ, rbenv là chỉ quan tâm đến phiên bản chuyển đổi, nhưng một hệ sinh thái thịnh vượng của plugin sẽ giúp bạn làm tất cả mọi thứ installing Ruby-setting up your environment, managing "gemsets" và thậm chí automating bundle exec.

Tôi không hoàn toàn chắc chắn về hỗ trợ của IRC đối với việc chuyển đổi các phiên bản Ruby và rbenv được thiết kế đơn giản và dễ hiểu, không yêu cầu hỗ trợ. Nhưng nếu bạn cần trợ giúp, trình theo dõi vấn đề và Twitter chỉ là một vài lần nhấp chuột.

Tiết lộ: Tôi là tác giả của rbenv, ruby-build và rbenv-vars.

+13

Cảm ơn bạn đã dành thời gian để đưa ra một câu trả lời tuyệt vời như vậy. – superluminary

+2

Wow, cảm ơn vì lời giải thích dễ hiểu và dễ hiểu như vậy. Một giáo viên tự nhiên sinh ra. – racl101

+2

dường như .ruby-phiên bản cũng sẽ làm như vậy. – alexzg

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

Cung cấp cho bạn khoảng:

< 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/[email protected] 
*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 

Và nó prepends:

$HOME/.rvm/gems/jruby-1.6.6/bin:$HOME/.rvm/gems/[email protected]/bin 

để $PATH

18

tôi đã viết một bài viết chuyên sâu: http://niczsoft.com/2011/11/what-you-should-know-about-rbenv-and-rvm/

Sự khác biệt cơ bản là nơi môi trường vỏ được thay đổi:

  • RVM: nó thay đổi khi bạn thay đổi Ruby.
  • rbenv: thay đổi khi bạn chạy tệp thực thi Ruby/gem.

Ngoài ra, các điều về RVM là, nó bao gồm rất nhiều sau đó Hồng ngọc chỉ quản lý, nó có nhiều hơn so với bất kỳ công cụ khác (có những người khác ngoài RVM và rbenv: https://twitter.com/#!/mpapis/status/171714447910502401)

Đỗ đừng quên hỗ trợ ngay lập tức bạn nhận được trên IRC trong kênh "#rvm" trên các máy chủ Freenode.

+1

Cảm ơn, thật tuyệt vời khi mọi người từ cả hai cộng đồng tham gia. – superluminary

13

Vì vậy, để tóm tắt các câu trả lời xuất sắc ở trên, sự khác biệt thực tế chính giữa RVM và rbenv là khi phiên bản Ruby được chọn.

rbenv:

rbenv thêm một shim khi bắt đầu con đường của bạn, một lệnh có cùng tên như Ruby. Khi bạn nhập ruby tại dòng lệnh, shim sẽ được chạy thay thế (vì nó cũng được gọi là "ruby" và xuất hiện đầu tiên trong đường dẫn). Các shim tìm kiếm một biến môi trường hoặc .rbenv_version tập tin để cho nó biết phiên bản của Ruby để đại biểu.

RVM:

RVM cho phép bạn thiết lập một phiên bản của Ruby trực tiếp bằng cách gọi rvm use. Ngoài ra, nó cũng ghi đè lệnh hệ thống cd. Khi bạn cd vào thư mục chứa tệp .rvmrc, mã bên trong tệp .rvmrc được thực thi. Điều này có thể được sử dụng để thiết lập một phiên bản Ruby, hoặc bất cứ điều gì khác bạn ưa thích.

khác biệt:

Tất nhiên có sự khác biệt khác. RVM có gemets ra khỏi hộp, trong khi rbenv chỉ đòi hỏi một chút hack hơn (nhưng không nhiều). Cả hai đều là giải pháp chức năng cho vấn đề.

5

Sự khác biệt chính có vẻ là when and how ruby is switched. Ruby được bật:

  • cho RVM bằng tay (RVM sử dụng) hoặc tự động trong thay đổi thư mục
  • cho rbenv tự động mỗi lần một lệnh ruby ​​được thực hiện

RVM dựa trên biến đổi cd lệnh và lựa chọn thủ công Ruby theo rvm use. rbenv sử dụng trình bao bọc hoặc "shims" cho tất cả các lệnh ruby ​​cơ bản làm cơ chế mặc định để chọn ruby. RVM tạo trình bao bọc cho các công cụ dòng lệnh cơ bản như đá quý, cào, ruby, quá. Chúng được sử dụng ví dụ trong CronJobs (xem http://rvm.io/integration/cron/), nhưng chúng không phải là cơ chế mặc định để chuyển đổi phiên bản Ruby.

Vì vậy, cả hai phương pháp đều chọn "tự động" phiên bản Ruby phù hợp bằng cách ghi đè lệnh và sử dụng trình bao bọc. rvm ghi đè các lệnh shell như cd. rbenv ghi đè tất cả các lệnh ruby ​​cơ bản như ruby, irb, rake và gem.

Các vấn đề liên quan