LoginSignup
0
0

More than 1 year has passed since last update.

RVMをシェルスクリプト内で利用する場合の注意

Last updated at Posted at 2022-05-04

シェルスクリプト上ではRVMはそのままでは実行できない

#!/usr/bin/env bash

set -eu

rvm use 2.7.2

デプロイを自動化しようとして例えばこのようなことをすると、次のようなエラーが起こり、実際にrubyのバージョンが指定できない。

RVM is not a function, selecting rubies with 'rvm use ...' will not work.

You need to change your terminal emulator preferences to allow login shell.
Sometimes it is required to use `/bin/bash --login` as the command.
Please visit https://rvm.io/integration/gnome-terminal/ for an example.

コンパイルエラーのような感覚でこのエラーを読むと「RVMは関数ではありません」と読めてしまい混乱する ("RVMは関数でないから決して関数みたいな呼び出し方はするな" という類のエラーに見える)が、このエラーはむしろ「RVM関数ではありません」と読まれるべきものである。つまり、RVMはbinフォルダに入っているもの(/usr/local/rvm/bin/rvmなど)を直接使うのではなく、同名のBash関数として定義されたものでなければ正しく機能しないらしい。

追記: 調べてみた

bin というフォルダに入っているからといって、その中にある実行ファイルが binary であるとは限らないようだ!(実質的な動作の違いはさほどないからだろうか?) /usr/local/rvm/bin/rvmテキストとして読めるBashスクリプトだった。ログインシェルの中でのみ、自動的に必要なファイルが読まれ、rvmがshの関数に置き変わる。

# シェルスクリプトで type rvm を実行すると
$ cat ./test.sh
#!/usr/bin/env bash
type rvm
$ ./test.sh
rvm is /usr/local/rvm/bin/rvm

# しかしシェルプロンプトから直接実行すると
$ type rvm
rvm is a function
(関数が吐かれる)

一旦特定のファイルをsourceする必要がある

シェルスクリプトで使う場合にのみ、次のパスのどちらかにあるファイルを source しないと動作しない

source "$HOME/.rvm/scripts/rvm" # $HOMEにあるなら
source "/usr/local/rvm/scripts/rvm" # システムレベルであるなら

これを実行すると、 rvm が関数に置き換えられて use などのサブコマンドが使えるようになる。

それでも落ちる場合

set -eu をしているとこの source および rvm コマンドは失敗する。

#!/usr/bin/env bash

set -eu

source "/usr/local/rvm/scripts/rvm"

rvm use 2.7.2
/usr/local/rvm/scripts/functions/support: 行 182: _system_name: 未割り当ての変数です (英語の場合"Unbound variable")

どうやら rvm は未割り当て変数が存在する前提で動作するようになっているらしい。
そのため、 rvm コマンドの操作が終わるまでは、 set +u を明示的に指定した上でコマンドの実行が妨げられないようにしなければならない。
rvm を実行し終わった後は set -eu しても構わない。

期待通り動作するスクリプトの例

#!/usr/bin/env bash

set +u # WTF: rvmコマンド群の未定義変数エラーを回避

source "/usr/local/rvm/scripts/rvm"
rvm use 2.7.2

set -eu # エラー処理を元に戻す

bundle install
bundle exec something
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0