拓冰建站拓冰建站
首页 / 资讯中心 / 正文

macOS 升级 Ruby 版本实践:rbenv 安装与配置全指南

最近在一台刚到手的新 MacBook 上配置开发环境跑项目依赖时第一行命令就给我一个下马威ruby 2.6.10已经终止支持一堆 gem 装不上而系统里自带的 Ruby 版本比社区主流整整落后了好几年。这个场景我相信很多 macOS 开发者都遇到过。很多人想升级 macOS 上的 Ruby 版本但打开教程发现方案五花八门什么rvm、rbenv、brew install ruby还没动手就先晕了。这篇文章就是把“升级 Ruby 版本”这件事彻底讲透从方案选型、环境搭建、具体命令到常见坑位排查一条龙梳理清楚适合刚接触 Ruby 或者被系统版本坑过的人直接照着做。1. 升级前先想清楚为什么 macOS 上 Ruby 版本这么难搞1.1 系统自带 Ruby 的几个大坑macOS 虽然自带 Ruby但这个 Ruby 并不是给开发者准备的。它主要是给系统脚本、自带工具链用的所以版本更新非常保守。比如 macOS Monterey 自带的 Ruby 是 2.6.8到了 Sonoma、Sequoia 之后虽然版本有所提升但依然跟不上 Ruby 官方每年一个大版本的节奏。而 Rails 7/8、Jekyll、Fastlane 这些常用工具对 Ruby 版本的要求越来越高新版本 gem 普遍要求 Ruby 3.0 以上用系统 Ruby 去跑基本就是寸步难行。更麻烦的是系统 Ruby 被系统完整性保护SIP锁得死死的。即使你想用sudo gem update --system强行升级也会发现要么权限不足要么直接改坏了系统依赖。我见过有人硬改/usr/bin/ruby最后系统里一堆工具报错只能重装系统。所以第一条原则就是永远不要试图去升级 macOS 自带的 Ruby你真正要做的是在系统里装一个独立的、由你控制的 Ruby 环境。1.2 升级方案怎么选rbenv、RVM、Homebrew 到底用哪个升级 Ruby 的常规方案其实就三个Homebrew 直接装、RVM、rbenv。我用一张表把它们的区别列出来看得更清楚。方案版本管理项目级切换上手难度系统侵入性推荐度Homebrew 直接安装只装一个最新版不支持最低中偏低RVM支持多版本支持但较重中高一般rbenv支持多版本非常轻量低低强烈推荐Homebrew 直接brew install ruby是最省事的装完就是一个新版本 Ruby简单粗暴。但它只能维护一个版本如果你同时有一个老项目要 Ruby 2.7一个新项目要 Ruby 3.3它就没法满足需求了。RVM 功能很强大安装卸载、切换、gemset 都有但它会在 shell 里注入自己的函数运行时会有些“重”在团队协作中容易带来环境差异。rbenv 是我最推荐的方式它本质上只做一件事通过 shim 机制改变ruby命令的指向。不同的目录可以绑定不同版本的 Ruby切换成本几乎为零而且完全不碰系统 Ruby安全干净。Rails 官方文档也明确推荐使用 rbenv这也是我下面所有实操步骤的基础。2. 环境准备与工具链搭建2.1 先装好 Homebrew在 macOS 上装 rbenv最省事的方式是通过 Homebrew。所以不管你有没有先检查一下自己电脑上是否已经安装了 Homebrew。打开终端输入brew -v如果返回版本号说明已经装好了。如果没有就执行 Homebrew 官方安装脚本/bin/bash -c $(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)这个脚本会自动安装 Xcode Command Line Tools可能会弹出一个窗口让你确认。这个过程需要几分钟甚至更久取决于网络状况。装完之后建议执行brew doctor确认一下环境是否健康。如果brew doctor提示有警告比如路径不对、目录权限有问题先处理掉再继续否则后面装 rbenv 会遇到各种奇怪的问题。2.2 安装并初始化 rbenvHomebrew 就绪后安装 rbenv 本身其实只有一条命令brew install rbenv ruby-build这里有两个组件rbenv负责版本管理ruby-build负责把指定版本的 Ruby 源码下载下来并编译安装。很多教程只写了brew install rbenv导致后面执行rbenv install的时候提示找不到命令所以记得把ruby-build一起装上。装好之后需要初始化 rbenv不过先不要急初始化要和 shell 配置一起做下面展开。这里可以先验证一下 rbenv 是否安装成功rbenv version如果输出system说明 rbenv 已经认识到了当前用的是系统 Ruby。2.3 把 rbenv 正确挂进 shellrbenv 的原理是在PATH环境变量前面插入一个 shims 目录当你在终端输入ruby时实际先执行的是 shims 里的小脚本它会根据当前目录的版本配置把命令转发给对应版本的 Ruby。所以要实现这个机制必须在 shell 启动时执行eval $(rbenv init -)。macOS 默认 shell 是 zsh所以把这一行加到~/.zshrc里echo eval $(rbenv init -) ~/.zshrc如果你用的是 bash则加到~/.bash_profileecho eval $(rbenv init -) ~/.bash_profile改完之后执行source ~/.zshrc让配置立刻生效或者干脆关掉终端重新开一个。然后验证一下which ruby正常情况下你会看到输出路径是/Users/你的用户名/.rbenv/shims/ruby而不是/usr/bin/ruby。如果显示的还是系统路径说明 rbenv 没有生效先别往下走回头检查配置是否写对、是否 source 了正确文件。3. 核心实操用 rbenv 安装并切换 Ruby 版本3.1 查看可用版本和当前版本环境搭好之后先看看 rbenv 能装哪些 Ruby 版本rbenv install -l这个列表很长全是版本号从 Ruby 1.8 到最新版都有。我一般会先筛一下稳定版rbenv install -l | grep -E ^\s*3\.[234]\.[0-9]$这样能看到当前可安装的 3.2、3.3、3.4 系列版本。选版本的时候要结合你的项目实际情况。如果是新项目直接用最新稳定版如果是老项目看看Gemfile顶部有没有ruby x.x.x的声明尽量匹配。同时也可以用ruby -v看一眼当前生效的版本方便后面对比。3.2 安装指定版本并设置为全局版本确定好版本号之后安装命令是rbenv install 3.3.5这里的3.3.5可以替换成你需要的版本号。这个命令会从源码编译 Ruby耗时较长一般来说 5 到 15 分钟都是正常的。编译期间终端会有大量输出不要一看滚动就以为卡住了只要不是长时间完全静止就耐心等着。装完之后要让这个版本变成全局默认版本rbenv global 3.3.5然后执行rbenv rehash重新生成 shims 脚本让新的 Ruby 版本被正确接管。验证一下ruby -v如果输出ruby 3.3.5p...并且which ruby指向~/.rbenv/shims/ruby说明升级成功。这时候如果再执行rbenv versions就能看到列表里既有system又有3.3.5当前版本前会带一个星号。3.3 项目级版本管理与 .ruby-version 文件全局版本解决的是“默认用哪个 Ruby”的问题但实际开发中经常同一个电脑上不同项目要求不同的 Ruby。rbenv 最方便的地方就在这里你可以进入某个项目目录单独指定一个版本。cd ~/work/legacy_project rbenv local 3.3.5这条命令会在当前目录生成一个名为.ruby-version的文件里面只有一行版本号。之后只要你在这个目录及其子目录下打开终端rbenv 就会自动切换成.ruby-version指定的版本离开这个目录则回到全局版本。这个.ruby-version文件建议提交到 Git 仓库里这样团队所有人进入项目后用rbenv就能自动切换到相同版本避免“我本地能跑你本地跑不了”的扯皮问题。如果项目里用了 asdf 这种多语言版本管理工具也可以兼容相同格式的.tool-versions。3.4 gem 与 bundler 的配套设置Ruby 版本切换好了gem 的安装路径也跟着变了。因为 rbenv 管理的 Ruby 装在用户目录下所以gem install不再需要sudo也没有系统目录权限问题。你可以先确认一下 gem 的环境gem env home正常情况下这个路径会在.rbenv/versions/3.3.5/lib/ruby/gems/...下面而不是系统目录。如果你的 gem 源在国内建议把源换成 Ruby China 的镜像gem sources --add https://gems.ruby-china.com/ --remove https://rubygems.org/然后安装 bundlergem install bundler后续在项目里执行bundle install所有 gem 都会安装到当前 Ruby 版本对应的 gems 目录互不干扰。记住只要是通过 rbenv 管理的 Ruby所有 gem 命令都不需要加sudo一旦你发现自己又需要sudo了那多半是因为命令走回了系统 Ruby赶紧检查一下which gem。4. 升级路上的常见问题与排查技巧4.1 编译失败 / 缺少依赖用rbenv install安装 Ruby 时最常遇到的就是编译失败报错信息五花八门但核心问题基本都是缺少依赖库。常见的有checking for openssl/ssl.h... no或者checking for libyaml... no这是因为 ruby-build 在编译时依赖 OpenSSL、Readline、LibYAML、zlib 等库。解决办法是先把这些依赖装全brew install openssl readline libyaml zlib装完之后仍然保留旧的编译命令最好设置一下环境变量让编译器能找到这些库。以 OpenSSL 为例export RUBY_CONFIGURE_OPTS--with-openssl-dir$(brew --prefix openssl)然后重新执行rbenv install。如果报错信息里出现Unknown option: --with-openssl-dir说明 ruby-build 版本太旧先执行brew upgrade ruby-build再试。不同 macOS 版本和不同 Ruby 版本组合具体依赖可能略有差异但“把 brew 依赖装全 指定 openssl 路径”这一套组合拳能解决大多数编译问题。4.2 切换后 ruby -v 没变化 / 命令找不到这是一类特别让人抓狂的问题明明执行了rbenv global 3.3.5ruby -v却还是老的。出现这种问题先按顺序排查。第一步检查which ruby。如果路径不是~/.rbenv/shims/ruby说明 rbenv init 没生效或者 PATH 顺序不对。重新执行source ~/.zshrc再看看echo $PATH里~/.rbenv/shims是不是排在最前面。第二步如果which ruby指向 shims但版本没变很可能是 shell 缓存了旧命令路径执行hash -r然后重新运行ruby -v。第三步如果你改变过~/.zshrc但新开的终端依然不生效检查一下终端是不是登录 shell。macOS 上使用 bash 的话配置要写进~/.bash_profile而不是~/.bashrc因为 bash 作为登录 shell 只加载前者这是很多人踩过坑的地方。4.3 gem 装在系统目录 / 权限报错执行gem install时如果出现permission denied rb_sysopen这类报错大概率是当前 Ruby 还是系统版。rbenv 管理的 Ruby 位于用户目录写入权限完全没问题根本不需要 sudo也不会出现权限错误。遇到权限问题第一步还是看which ruby和which gem。如果两个都不在 rbenv 的 shims 路径下说明 shell 环境没初始化好回到 4.2 排查。如果ruby在 rbenv 下而gem不在可以用rbenv rehash重新生成 gem 命令的 shims因为安装新 Ruby 后 gem 命令可能没有及时生成。另外一个常见误区是直接执行sudo gem install这会把 gem 装到系统 Ruby 目录污染系统环境也会让版本管理彻底混乱。记住了rbenv 环境里永远不需要 sudo。4.4 疑难杂症速查表下面这张表是我实际工作中遇到过的几个高频问题直接对照参考即可。问题现象可能原因解决办法rbenv: version x.x.x is not installed.ruby-version指定了一个没装过的版本rbenv install x.x.x安装对应版本rbenv install下载源码时 404ruby-build 版本太旧不认识新版本brew upgrade ruby-buildrequire cannot load such file -- openssl编译时没链接 OpenSSL设置RUBY_CONFIGURE_OPTS后重装 Rubybundle exec rails找不到命令依赖没装到当前 gem 环境执行bundle install优先用bundle execrbenv: command not foundHomebrew 路径不在 PATH 中或没执行 init检查 shell 配置和 PATHRuby 版本切换成功但 gem 路径没变没有执行rbenv rehash执行rbenv rehash重开终端5. 升级完成后的验证与日常使用建议5.1 如何确认升级成功升级不能被一条ruby -v就糊弄过去我建议你做一次完整的验证确认当前 Ruby 来自 rbenv 管理目录而不是系统目录。在终端依次执行下面几条命令which ruby ruby -v which gem gem -v gem env home rbenv versions我预期的结果大概是这样的/Users/你的用户名/.rbenv/shims/ruby ruby 3.3.5p100 (2024-09-03 revision 1c634b6a0d) [arm64-darwin23] /Users/你的用户名/.rbenv/shims/gem 3.5.16 /Users/你的用户名/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0 system * 3.3.5 (set by /Users/你的用户名/.rbenv/version)只要which ruby出现在.rbenv/shims下并且gem env home指向.rbenv/versions里的目录就说明升级是成功的。如果你看到/usr/bin/ruby说明前面有一步没做对别急着往下先回第 2 章查配置。5.2 日常升级 Ruby 版本的操作路径rbenv 装好后以后 Ruby 出了新版本升级流程其实已经形成了一个固定套路。想查看当前可安装的新版本执行rbenv install -l选好版本号后用rbenv install安装装完rbenv global切换全局版本再rbenv rehash。如果是针对某个项目升级就进入项目目录执行rbenv local并更新.ruby-version。升级大版本号时比如从 3.2 升到 3.3需要额外注意Gemfile里声明的 Ruby 版本约束以及一些编译型 gem 是否需要重新编译。我的习惯是升级前先bundle install保存当前锁文件升级后再重新执行bundle install有报错就根据报错逐个处理。每升一个版本我会先在测试环境跑一遍完整的测试用例确认没问题再切换到日常开发。5.3 一些实用的小技巧和避坑心得文章最后分享几个我实际操作中总结出来的技巧。第一在项目里一定提交.ruby-version文件。哪怕你是单人开发半年后回头看自己的项目也会忘记当时用的哪个 Ruby 版本有文件在就不用靠猜。第二不要同时用 rvm 和 rbenv二者会在 shell 里互相打架。如果之前装过 rvm需要先彻底卸载再装 rbenv否则会出现各种莫名其妙的命令覆盖问题。第三rbenv global设置的是一个全局兜底版本如果你在某个目录下发现执行的 Ruby 版本不对先看看当前目录有没有.ruby-version有没有被它“绑定”成了一个旧版本。排查顺序永远是命令行里输入的which ruby、当前目录的.ruby-version、全局的rbenv version。第四如果团队已经用了 Docker 开发环境Ruby 版本的管理其实可以做成镜像的一部分本机只需要一个足够新的 Ruby 跑基础脚本就行。但当你想在本地快速验证某个 gem 或一段脚本时rbenv 的轻量灵活还是无可替代。我至今在任何 macOS 开发机上都会先装 rbenv因为它是少有的、配置一次就能用很多年还不用怎么操心版本管理工具。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门