【问题标题】:Install Latest Stable Version of Ruby Using rbenv使用 rbenv 安装最新的稳定版 Ruby
【发布时间】:2015-07-22 15:42:56
【问题描述】:

我想安装rbenv 提供的最新稳定版Ruby。这个特性 won't be happening 在 rbenv 本身中。

当我在我的 shell 中运行命令 rbenv install -l 时,我会得到一长串可用版本。该列表包含所有类型的条目。以下是展示格式和多样性的部分列表:

$ rbenv install -l
Available versions:
  2.0.0-p643
  2.0.0-p645
  2.1.0-dev
  2.1.0-preview1
  2.1.0-preview2
  2.1.0-rc1
  2.1.4
  2.1.5
  2.1.6
  2.2.0-dev
  2.2.0-preview1
  2.2.0-preview2
  2.2.0-rc1
  2.2.0
  2.2.1
  2.2.2
  2.3.0-dev
  jruby-1.7.19
  jruby-1.7.20
  jruby-9.0.0.0-dev
  jruby-9.0.0.0+graal-dev
  jruby-9.0.0.0.pre1
  jruby-9.0.0.0.pre2
  maglev-1.0.0
  maglev-1.1.0-dev
  maglev-2.0.0-dev
  mruby-dev
  mruby-1.0.0
  mruby-1.1.0
  rbx-2.5.2
  rbx-2.5.3
  ree-1.8.7-2011.12
  ree-1.8.7-2012.01
  ree-1.8.7-2012.02
  topaz-dev

我的目标是在 VERSION 是最高 x.x.x 版本的 shell 脚本中自动执行命令 rbenv install VERSION。换句话说,我需要自动将列表中以数字开头且不以-something 结尾的最高条目替换为VERSION。从这个列表中,我需要2.2.2

我可以在我的 shell 脚本中添加什么来自动选择命令 rbenv install x.x.x 中最高的 x.x.x 版本?

编辑:由于尚未安装 Ruby,因此解决方案必须使用 Bash 而不是 Ruby。

编辑 2:我想要 Ruby 的 MRI(主流)版本。

【问题讨论】:

  • 在我看来,您只想要列表中以数字开头的最后一个(因为您显然想要 MRI)并且没有 predevrc# 在其名称)。这样的事情会起作用:lines.reverse_each.find {|version| version =~ /^\d/ && version !~ /pre|dev|rc\d/ }
  • (我不能保证这将永远有效,但也许它会帮助您入门。如果您好奇 ruby​​-build 如何对列表进行排序,您可以在此处查看:@987654323 @)
  • 感谢@Jordan 的 cmets。尽管尚未安装 Ruby,但我需要将结果保存在 Bash 中。很高兴知道排序算法,谢谢指出。
  • 我发布了一个我想出的快速而肮脏的解决方案。如果有人想写一个更准确的答案,我很乐意接受。
  • 您可以安装 Ruby 的 MRI 版本。只需使用 Rubinius 编译安装它的脚本。

标签: ruby bash shell sed rbenv


【解决方案1】:

简单解决方案(直接安装最新稳定版):

rbenv install $(rbenv install -l | grep -v - | tail -1)

解释:

rbenv install -l | grep -v - | tail -1

过滤掉所有包含连字符 - 的版本,即所有非 MRI 版本和预发布 MRI 版本。然后选择最后一个,保证是最高的,因为 ruby​​-build 输出已经按照版本号升序排序了。

【讨论】:

  • 不错的方法。我没有注意到 MRI 版本是唯一没有任何连字符的版本。
  • 当我尝试将其分配给 shell 变量时,该值有一些导致错误的前导空格。这解决了问题: LATEST_RUBY_VERSION="$(rbenv install -l | grep -v - | tail -1 | tr -d '[[:space:]]')"
【解决方案2】:
rbenv install -l | awk -F '.' '
   /^[[:space:]]*[0-9]+\.[0-9]+\.[0-9]+[[:space:]]*$/ {
      if ( ($1 * 100 + $2) * 100 + $3 > Max ) { 
         Max = ($1 * 100 + $2) * 100 + $3
         Version=$0
         }
      }
   END { print Version }'
  • 取最大的版本(排序或不排序)

如果列表已排序,则更简单的 sed(posix 版本)就足够了

rbenv install -l | sed -n '/^[[:space:]]*[0-9]\{1,\}\.[0-9]\{1,\}\.[0-9]\{1,\}[[:space:]]*$/ h;${g;p;}'

【讨论】:

  • 对于任何使用 Debian 的人(至少从 Debian 8 Jessie 起)的注释——出于某种原因,awk 的默认版本不支持[[:space:]]。只需将其替换为 [ \t] 即可获得相同的结果。
【解决方案3】:

在使用 rbenv 安装时,应首先更新 ruby​​-build 以获得最新版本的 ruby​​。 请按照以下步骤操作:

  • brew reinstall --HEAD ruby-build ( 如果 rbenv 已经安装, brew 可能会出现一些错误,然后继续前进
    • brew unlink ruby-build
    • brew install --HEAD ruby-build )
  • brew upgrade
  • 然后您可以使用上面建议的上述方法之一自动安装最新版本或简单地rbenv install <required latest version>

在 macOS 10.13.6 中工作

【讨论】:

  • 我尝试简单地升级 ruby​​-build,然后卸载并重新安装 ruby​​-build。都没有奏效。这行得通。
【解决方案4】:

经过相当多的反复试验后,我找到了一种从该列表中获取最新稳定版本的方法。这并不完美,因为它只是抓住了正确的模式和它的最后一个版本,但它应该可以完成工作。只要版本有序,它就可以工作。

这将产生2.2.2

rbenv install -l | grep -P "^  [[:digit:]]\.[[:digit:]]\.[[:digit:]]$" | tail -1

我们可以像这样将结果插入rbenv install

rbenv install $(rbenv install -l | grep -P "^  [[:digit:]]\.[[:digit:]]\.[[:digit:]]$" | tail -1)

【讨论】:

  • 如果最新的稳定版本有补丁号(例如2.0.0-p645),那不会得到最新的稳定版本,是吗?您肯定想要最新的补丁级别,因为它们通常包含安全修复程序。
  • @Jordan Ruby 不再使用补丁号。请参阅ruby-lang.org/en/news/2013/12/21/… 最新的稳定和修补版本将由最新的 teeny 版本表示,这正是此代码所确定的。
  • 啊。那么,这让它更容易一些。
  • @TomDworzanski - 谢谢。我想知道补丁编号发生了什么。
【解决方案5】:

我的答案类似于 Anonymous 的答案(但更短,因为我使用的是 \d)。

rbenv install -l|  grep -P "\s2.*(\.|\d)\d$" | tail -1

我想指定最新的jruby,这就是我使用“2”的原因,所以我可以将2替换为“jruby”:

rbenv install -l|  grep -P "\sjruby.*(\.|\d)\d$"|tail -1

您可以用其他字符串替换 jruby 以获得不同类型的 ruby​​,例如rbx,mruby。

【讨论】:

    【解决方案6】:

    您可以为此使用 xxenv-latest 插件,该插件也适用于 nodeenv、pyenv 等。

    您提到了自动化;这是我用来设置最新 Ruby 的完整命令列表:

    # Install rbenv
    brew install rbenv
    
    # Initialize rbenv to run now
    eval "$(rbenv init -)"
    
    # Install xxenv-latest rbenv plugin
    git clone https://github.com/momo-lab/xxenv-latest.git "$(rbenv root)"/plugins/xxenv-latest
    
    # Install latest Ruby and set as global
    rbenv latest install
    rbenv latest global
    

    【讨论】:

      【解决方案7】:

      我宁愿在 Ruby 中而不是在 bash 中。

      versions = `rbenv install -l`
      versions.split("\s").select{|v| v.match( /^\d*\.\d*\.\d*$/ )}.last
      

      【讨论】:

      • 我也是 :) 但是 Ruby 尚未安装 ;) +1 为 Ruby 解决方案 :)
      • 我相信可以使用 Rubinius 编译可执行文件:rubini.us/2011/03/17/running-ruby-with-no-ruby
      • 我研究了 Rubinius 解决方案。它只根据我的判断生成 Rubinius 字节码。所以我仍然需要他们的虚拟机或其他任何东西来执行代码。它不是编译的机器代码,我需要先安装 Rubinius 才能做到这一点。
      • 哦,我明白了。对于那个很抱歉。看来你是对的。
      • 看来你可以使用 Releasy: github.com/Spooner/releasy 。它已经几年没有更新了,但我不明白为什么它不起作用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多