12

(See update at bottom)


I feel like I'm missing something terribly obvious here, but I can't change gemsets from within a shell script. This minimal script demonstrates:

#!/usr/bin/env bash

rvm gemset use "testing"

I even tried the instructions from the Scripting RVM page (although it didn't seem necessary):

#!/usr/bin/env bash

# Load RVM into a shell session *as a function*
if [[ -s "$HOME/.rvm/scripts/rvm" ]] ; then
  # First try to load from a user install
  source "$HOME/.rvm/scripts/rvm"
elif [[ -s "/usr/local/rvm/scripts/rvm" ]] ; then
  # Then try to load from a root install
  source "/usr/local/rvm/scripts/rvm"
else
  printf "ERROR: An RVM installation was not found.\n"
fi

rvm gemset use "testing"

Still no go.

Interestingly enough, if I try to run the script without first creating the "testing" gemset, I get ERROR: Gemset 'testing' does not exist, rvm gemset create 'testing' first. However, if I create the gemset and then run the script, I get no output from the script and the gemset is not changed (according to rvm info). I am able to perform other RVM gemset actions, such as creating gemsets and trusting .rvmrc files, from within the script.

[Update]

Of course, the environment is changing, as indicated by a call to rvm info from within the script. How do I get these changes to persist/affect the calling shell? Or, if that's not possible (as indicated here), is there any way to set the current RVM gemset based on input to a script?

Community
  • 1
  • 1
Michelle Tilley
  • 157,729
  • 40
  • 374
  • 311
  • your headline shows you using backquotes. Are you really using them? You know that means command-substitution? any output from that command would have to be in the form of varName=value to be useful (plus most likely, a preceeding eval). Good luck! – shellter Apr 26 '11 at 16:35
  • No, I'm not, I just used them in the title to indicate a command. – Michelle Tilley Apr 26 '11 at 16:37

3 Answers3

20

Had exactly the same problem, and here's the solution:

#!/bin/bash

# IMPORTANT: Source RVM as a function into local environment.
#            Otherwise switching gemsets won't work.
[ -s "$HOME/.rvm/scripts/rvm" ] && . "$HOME/.rvm/scripts/rvm"

# Enable shell debugging.
set -x

rvm 1.9.2@gemset_a
rvm gemdir
gem env gemdir

rvm 1.9.2@gemset_b
rvm gemdir
gem env gemdir

What I've found out is that your interactive shell has got rvm() and its helpers, whereas script's environment has not got them. rvm binary is executed instead, partially working and thus causing some confusion.

Alex Fortuna
  • 1,223
  • 12
  • 16
  • Thanks! This was killing me with my Jenkins/Capistrano deploy! I was soooo confused! Cheers. – Harmon Nov 09 '12 at 18:29
  • Thanks! This also helped fix an issue where switching Ruby version (e.g. "rvm system") didn't work inside a script. – Henrik N Dec 12 '12 at 19:26
  • 1
    `#!/bin/bash --login` will also do the trick if you don't want to have to add `[ -s "$HOME/.rvm/scripts/rvm" ] && . "$HOME/.rvm/scripts/rvm"` – User128848244 Oct 23 '15 at 19:35
1

I ended up implementing the functionality I wanted as a function instead of a shell script.

function rvmrc {
  rvm gemset create $1
  rvm gemset use $1
  echo "rvm gemset use $1" > .rvmrc
  rvm rvmrc trust
}
Michelle Tilley
  • 157,729
  • 40
  • 374
  • 311
  • Thanks - this solves a bunch of issues for me and can be used with other things. Seems obvious when you show it here but I've been fiddling with this for hours! – Richard Jordan Feb 13 '12 at 06:18
0

RVM isn't loading correctly because it loads on your .bashrc or .bash_profile, which are run at login.

You can run the rvm gemset use with a login shell:

bash -l -c "rvm use RUBY_VERSION@GEMSET_NAME"

Hope it helps!

jpbalarini
  • 1,082
  • 1
  • 17
  • 23