Ubuntu执行sudo gem update --system报错 无法更新OS所属Ruby文件
问题原因
Ubuntu 预装的 RubyGems 是发行版做过定制修改的版本,报错提及的 rubygems/defaults/operating_system.rb 是 apt 源中 rubygems 包自带的系统级定制文件,不属于 RubyGems 上游原生内容。直接执行 sudo gem update --system 会拉取上游原生版本覆盖系统安装的 RubyGems,和该定制文件产生版本冲突,直接抛出对应报错。此前修改gems库权属的操作不会触及这个系统路径下的定制文件,因此完全无效。
解决方案
按稳定性优先级从高到低可选以下方案:
- 方案1(最推荐):使用Ruby版本管理工具搭建独立环境,不修改系统自带Ruby
系统自带Ruby主要供系统内部依赖Ruby的组件(比如部分apt逻辑、系统服务)使用,日常开发不要直接调用。安装rbenv/rvm这类版本管理工具,在用户目录下部署独立Ruby环境,操作全程不需要sudo,也不会和系统文件产生冲突:- 先安装编译依赖:
sudo apt install git curl libssl-dev libreadline-dev zlib1g-dev autoconf bison build-essential libyaml-dev libncurses5-dev libffi-dev libgdbm-dev- 安装rbenv和ruby-build插件后,部署所需的Ruby版本,在这个独立环境下执行
gem update --system不会触发任何冲突。
- 方案2(适合仅使用系统Ruby的场景):通过apt源升级RubyGems
不要直接用gem命令升级系统级RubyGems,使用Ubuntu官方维护的适配包升级即可,不会产生文件冲突:- 如果之前递归修改过系统Ruby目录的权限,先恢复默认权属避免后续异常:
sudo chown -R root:root /usr/lib/ruby/vendor_ruby/rubygems/- 执行apt升级命令:
sudo apt update && sudo apt install --only-upgrade rubygems ruby-full - 方案3(不推荐,仅作临时绕过):手动移除冲突的定制文件后升级
如果一定要直接用gem命令升级系统自带RubyGems,可以先把冲突的定制文件备份移除:
再执行sudo mv /usr/lib/ruby/vendor_ruby/rubygems/defaults/operating_system.rb /usr/lib/ruby/vendor_ruby/rubygems/defaults/operating_system.rb.baksudo gem update --system即可完成升级,注意升级完成后不要把备份的定制文件移回,否则版本不兼容会持续报错。
注意事项
不要随意递归修改/usr/lib/ruby/路径下的文件权属,很容易导致依赖系统Ruby的组件运行崩溃。如果已经把系统Ruby环境改乱,可以执行sudo apt reinstall rubygems ruby把相关文件恢复到官方默认状态再操作。
内容的提问来源于stack exchange,提问作者Thomas Mikhail
相关产品推荐
相关产品推荐

