【问题标题】:Adaptive Ruby version when opening a terminal打开终端时的自适应 Ruby 版本
【发布时间】:2021-12-07 21:22:20
【问题描述】:

这个问题与this one相反(也问hereherehere

我安装了两个版本的 ruby​​

ubuntu:~/environment $ rvm list

       ruby-2.6.6 [ x86_64 ]
    =* ruby-3.0.2 [ x86_64 ]

每次我打开终端窗口时,都会设置 ruby​​-3.0.2(默认)。问题是对于我的几个旧项目,我必须使用 ruby​​-2.6.6,所以每次我都必须切换

rvm use 2.6.6

当我打开特定项目的终端窗口时,有没有办法自动选择 ruby​​ 2.6.6?我试图用 .ruby-version 文件覆盖默认的 rvm 版本(如建议的here),但它没有成功。

编辑文件 /home/ubuntu/.rvm/scripts/cd 包含以下内容

#!/usr/bin/env bash

# Source a .rvmrc file in a directory after changing to it, if it exists.  To
# disable this feature, set rvm_project_rvmrc=0 in /etc/rvmrc or $HOME/.rvmrc
case "${rvm_project_rvmrc:-1}" in
1|cd)
  # cloned from git@github.com:mpapis/bash_zsh_support.git
  source "$rvm_scripts_path/extras/bash_zsh_support/chpwd/function.sh"

  # not using default loading to support older Zsh
  [[ -n "${ZSH_VERSION:-}" ]] &&
  __rvm_version_compare "$ZSH_VERSION" -gt  4.3.4 ||
  {
    function cd()    { __zsh_like_cd cd    "$@" ; }
    function popd()  { __zsh_like_cd popd  "$@" ; }
    function pushd() { __zsh_like_cd pushd "$@" ; }
  }

  __rvm_after_cd()
  {
    \typeset rvm_hook
    rvm_hook="after_cd"
    if [[ -n "${rvm_scripts_path:-}" || -n "${rvm_path:-}" ]]
    then source "${rvm_scripts_path:-$rvm_path/scripts}/hook"
    fi
  }
  __rvm_cd_functions_set()
  {
    __rvm_do_with_env_before
    if [[ -n "${rvm_current_rvmrc:-""}" && "$OLDPWD" == "$PWD" ]]
    then rvm_current_rvmrc=""
    fi
    __rvm_project_rvmrc >&2 || true
    __rvm_after_cd || true
    __rvm_do_with_env_after
    return 0
  }
  [[ " ${chpwd_functions[*]} " == *" __rvm_cd_functions_set "* ]] ||
  chpwd_functions=( "${chpwd_functions[@]}" __rvm_cd_functions_set )

  # This functionality is opt-in by setting rvm_cd_complete_flag=1 in ~/.rvmrc
  # Generic bash cd completion seems to work great for most, so this is only
  # for those that have some issues with that.
  if (( ${rvm_cd_complete_flag:-0} == 1 ))
  then
    # If $CDPATH is set, bash should tab-complete based on directories in those paths,
    # but with the cd function above, the built-in tab-complete ignores $CDPATH. This
    # function returns that functionality.
    _rvm_cd_complete ()
    {
      \typeset directory current matches item index sep
      sep="${IFS}"
      export IFS
      IFS=$'\n'
      COMPREPLY=()
      current="${COMP_WORDS[COMP_CWORD]}"
      if [[ -n "$CDPATH" && ${current:0:1} != "/" ]] ; then
        index=0
        # The change to IFS above means that the \command \tr below should replace ':'
        # with a newline rather than a space. A space would be ignored, breaking
        # TAB completion based on CDPATH again
        for directory in $(printf "%b" "$CDPATH" | \command \tr -s ':' '\n') ; do
          for item in $( compgen -d "$directory/$current" ) ; do
            COMPREPLY[index++]=${item#$directory/}
          done
        done
      else
        COMPREPLY=( $(compgen -d ${current}) )
      fi
      IFS="${sep}";
    }
    complete -o bashdefault -o default -o filenames -o dirnames -o nospace -F _rvm_cd_complete cd
  fi
  ;;
2|prompt)
  if
    [[ -n "${ZSH_VERSION:-}" ]]
  then
    precmd_functions+=(__rvm_do_with_env_before __rvm_project_rvmrc __rvm_do_with_env_after)
  else
    PROMPT_COMMAND="${PROMPT_COMMAND%% }"
    PROMPT_COMMAND="${PROMPT_COMMAND%%;}"
    PROMPT_COMMAND="${PROMPT_COMMAND:-}${PROMPT_COMMAND:+; }__rvm_do_with_env_before; __rvm_project_rvmrc; __rvm_do_with_env_after"
  fi
  ;;
esac

【问题讨论】:

  • 你确定你有那个文件吗?我一直使用 .ruby-version,它对我有用。
  • 阳性。我还创建了一个 .rvmrc 文件,其中包含“rvm use 2.6.6@teamlink”行(teamlink 是项目的名称)。没有运气...
  • 你在 .ruby-version 中有什么?
  • 就在“2.6.6”这一行

标签: ruby-on-rails rvm


【解决方案1】:

您可能将 RVM 用作 shell 脚本,而不是 shell 函数。

您可以在典型的 shell(bash、zsh、...)中进行这样的检查:执行:type rvm

如果它显示 rvm is /home/ying/.rvm/bin/rvm :您正在用作脚本(在 $PATH 中找到)

如果它显示 rvm is a function :您正在使用函数(好多了)。

查看:https://rvm.io/rvm/basics#post-install-configuration

如果你作为脚本使用,并且想作为函数使用:你需要“source”rvm函数,它位于<rvm main folder>/scripts/rvm,例如如果安装在$HOME:

source $HOME/.rvm/scripts/rvm
source /usr/local/rvm/scripts/rvm

通常,在 RVM 安装时,它会在 .profile 的等效项中添加以下行(取决于 shell 以及它的全局或用户):

[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" # Load RVM into a shell session *as a function*

RVM 会自动更改版本,如下所述:

https://rvm.io/workflow/projects

为了检测.ruby-version,需要以下内容:

  • RVM 必须是支持该功能的最新版本
  • RVM 必须加载到 shell(通常通过 .profile 或等效文件)中,以便作为函数执行
  • shell 必须与此回调功能兼容(bash 和 zsh 是)

会发生什么:

  • 当您将 rvm 作为函数加载时,它会在 shell 中注册回调
  • 当您 cd 进入项目时,RVM 回调(在 shell 中)检测文件 .ruby-version(或其他)并自动执行 rvm use 的等效操作。

例如,我使用 zsh(在 osx 上),它有 preexecprecmd 回调 它检测 ruby​​ 版本文件并在我 cd 进入它或子文件夹时应用。 它也适用于 bash。

如果您好奇或想知道为什么它对您不起作用,请查看文件<rvm main dir>/scripts/cd

通常,shell 变量 chpwd_functions 设置为 __rvm_cd_functions_set 这是cd rvm 之后调用的函数

【讨论】:

  • type rvm 说我将它用作函数。有关 cd 文件的内容,请参阅我的原始帖子...
  • 所以,你打开了一个新的终端。在此终端中,您会在系统上获得一个登录 shell。 (通过 SSH,或者因为终端在本地运行)。然后将当前工作目录更改为项目。在这个目录中,有一个文件:.ruby-version。如果 rvm 作为函数加载并且 shell 钩子就位,它应该找到这个文件并更改 ruby​​ 版本。如果它不起作用,则上述步骤之一是错误的:
  • 好的,似乎当我打开终端然后将当前工作目录更改为项目时,.ruby-version 启动并选择了 2.6.6 版本。我正在做的是打开一个终端直接到项目。这不起作用,并且选择了默认版本 3.0.2。这是一个部分解决方案,但非常有用。谢谢...
猜你喜欢
  • 1970-01-01
  • 2017-11-11
  • 2023-03-11
  • 1970-01-01
  • 1970-01-01
  • 2022-06-17
  • 1970-01-01
  • 2013-09-23
  • 2017-12-10
相关资源
最近更新 更多