Using RVM with tcsh

RVM is a very useful tool for working with multiple Ruby interpreters, and it’s especially handy for testing libraries against multiple interpreters. Unfortunately (for me), it only works with bash, zsh, and similar shells, and I use tcsh—but I’ve found a workaround.

I suspect that very few people use tcsh these days, and that the proportion of Ruby programmers is lower still. But I do, for reasons that I’ll have to write about another time.

A comment by chetstone pointed me in the direction of a solution. tcsh doesn’t have functions, so it’s not possible to modify the current environment in quite the same way as RVM does in bash, but it’s easy enough to use RVM to modify a bash environment and then load tcsh within it. You only need to do this for certain commands, such as rvm use. Here’s how to do it:

First, install RVM:

> curl -Lo rvm-install.sh https://rvm.beginrescueend.com/install/rvm
> bash rvm-install.sh

Next, create an rvm.tcsh wrapper script somewhere in your path, and make it executable:

#!/usr/bin/env tcsh

set rvm_command="source ${HOME}/.rvm/scripts/rvm; rvm $*"

if ($1 == "use") then
  bash -c "$rvm_command && tcsh"
else
  bash -c "$rvm_command"
endif

Finally, add an alias to ~/.tcshrc:

alias rvm rvm.tcsh

From now on, when you type rvm in tcsh, it will pass that command to the real RVM. If the command starts with rvm use, you’ll be dropped into a new tcsh session using the specified RVM environment.

I’ve added annotations to my prompt to tell me if I’m in an RVM sub-shell (also in ~/.tcshrc):

set prompt_info = ""
if ($?RUBY_VERSION) then
  set prompt_info = "[$RUBY_VERSION] $prompt_info"
endif
# plus any other information you want

set prompt = "$prompt_info%. %# "
# yours may be more colourful

You can do all the normal kind of operations:

~ > ruby -v
ruby 1.8.7 (2010-06-23 patchlevel 299) [x86_64-linux]
~ > rvm install 1.9.2
Installing Ruby from source to: /home/paul/.rvm/rubies/ruby-1.9.2-p180,
this may take a while depending on your cpu(s)...
…
Install of ruby-1.9.2-p180 - #complete
~ > rvm use 1.9.2
Using /home/paul/.rvm/gems/ruby-1.9.2-p180
[ruby-1.9.2-p180] ~ > ruby -v
ruby 1.9.2p180 (2011-02-18 revision 30909) [x86_64-linux]

It’s a simple wrapper, but that’s all that’s needed to use most of RVM’s functionality.

Comments

  1. Joshua

    Wrote at 2011-04-01 08:52 UTC using Safari 6533.18.5 on Mac OS X:

    Lots of a people still use tcsh. In fact it’s still the leader in interactive tools over the other ‘scripting’ shells. So thank you for posting this. I’m unfortunately still having trouble however. I get lots of permission errors related to RVM trying to write into /usr/local. I’m sure I’ll get it sorted, but any tips would be appreciated.
  2. Paul Battley

    Wrote at 2011-04-01 11:09 UTC using Chrome 12.0.717.0 on Linux:

    Joshua, make sure you’re not using sudo with RVM. You might also need to delete any cached bundler files if you’re using that, and I’ve seen problems with old stuff in ~/.gem before.

    And yes, I agree with you – that’s why I still use it!
  3. Jim Meyer

    Wrote at 2011-04-05 22:04 UTC using Chrome 10.0.648.204 on Mac OS X:

    Excellently helpful! Thanks for making the effort to share this.

    I tweaked my setup minorly to be “bash -c $rvm_command && tcsh” and to put all the path-altering bits of my ~/.tcshrc into a conditional so they don’t run again in the new shell.

    Thanks again!
  4. Paul Battley

    Wrote at 2011-04-06 03:58 UTC using Chrome 12.0.722.0 on Linux:

    Jim, good point about the &&; I’ve changed my instructions accordingly.

    Could you share your path-altering code? I haven’t found a solution that avoids duplication when running nested shells (in tmux or screen) and still works via rvm.
  5. Paul Menon

    Wrote at 2011-04-25 04:49 UTC using Firefox 4.0 on Mac OS X:

    So tcsh is not just for the grey haired, I’m relieved to see that. I was beginning to feel like a dinosaur. Thankyou so much for your wrapper. It worked ferpectly [sic], apart from a syntax or two (tcsh alias sans ”=”). There are more gotchas in the rvm pages anyway. Thankyou also for delaying me having to change my shell. It will have to happen one day (given the prevalence of bash only scripts), but not now.

    Hi Jim, as Paul Battley indicated, it would be good to have a squiz at your code that obviates a new shell. Any chance of that?
  6. Paul Battley

    Wrote at 2011-04-25 08:44 UTC using Chrome 12.0.722.0 on Linux:

    Oops, thanks for spotting the mistake on the alias syntax, Paul. I’ve corrected that.
  7. Nick

    Wrote at 2011-08-17 19:28 UTC using Chrome 14.0.835.94 on Mac OS X:

    Regarding the path altering code: Since I reset the PATH completely in my .tcshrc, I needed to move all of my PATH setting statements into this:

    if ( ! ($?RUBY_VERSION) ) then
    # define all PATH stuff here
    endif

    Otherwise the RVM changes to PATH get removed when RVM loads.
  8. chetstone

    Wrote at 2011-11-12 21:45 UTC using Safari 533.21.1 on Mac OS X:

    @Paul, thanks for the mention. After making the comment you refer to, I just stopped using rvm, cause it was a bit of a hassle, and I didn’t really need it. Now I need to use it, and I find your implementation, which helps.

    I don’t like the fact, though, that it still requires starting a new shell, with loss of history.

    I don’t really understand why a program as useful and complex as rvm is implemented as a shell script. The people that invented and maintain it are heroes—- shell scripting is HARD. But it would be so much easier if it were implemented in, say, how about RUBY?. Sure, the program needs
    to modify the state of a current shell, but that can be done with a simple eval in any shell, bash, tcsh or otherwise.

    As an example, I have written a simple ruby script over here at https://gist.github.com/1361149 that invokes a bash subshell, runs rvm and returns a string to be eval’d. So you can run ‘rvm use’ without starting a new shell.
  9. Francis Trujillo

    Wrote at 2012-06-23 22:00 UTC using Firefox 10.0.4 on Linux:

    Thank you. This is EXACTLY what I needed. All of our design automation tools are based on tcsh for our cadflow env. I can now deploy Ruby apps and teach the masses on Ruby and Rails without the risk of gem files breaking any one project.
  10. Kimmo Suominen

    Wrote at 2012-07-08 19:31 UTC using Chrome 20.0.1132.47 on Mac OS X:

    In ~/.tcshrc (pretty much at the top of it):

    bc. #
    # Fix our path if we don’t seem to have done so yet.
    #
    if ( -r ~/.path && ”$path1” != ”$HOME/bin/$OSTYPE” ) source ~/.path

    In ~/.path:

    bc. #
    # The first entry is magic – check with .tcshrc also!
    #
    set p = ( ”$HOME/bin/$OSTYPE” ”$HOME/bin/share” )
    #
    # More code that adds directories to the $p array.
    #
    #
    # Set path only once instead of adding to it, to avoid expensive
    # directory scans.
    #
    set path = ( $p )
  11. Dan Hansen

    Wrote at 2012-07-13 01:00 UTC using Safari 534.57.2 on Mac OS X:

    Hey, many thanks. Only had to make a couple of custom modifications to get the prompt I wanted (I like using [m:%c3] and %n options in prompt so I can see the host and username I am working with] and it all seems to be working like a champ.

    RVM looks great – but it hardly seems like we’re moving the goalposts forward if the installation has to be custom-hacked to work with a shell that authors are not using. Hopefully tcsh is not that-dead-yet. That’s kind of like telling me I can only edit ruby in vi and not in emacs.

    I’m sure the authors have their reasons. Thanks again.
  12. Kerry Kartchner

    Wrote at 2013-05-13 01:31 UTC using Firefox 20.0 on Mac OS X:

    Thanks for this; I’m a tcsh curmudgeon, and dislike the implicit reliance on bash for RVM. Although, I have found I can live perfectly well just using rbenv.
  13. Eric

    Wrote at 2014-04-08 19:53 UTC using Chrome 33.0.1750.152 on Mac OS X:

    Thanks!!
  14. Martin

    Wrote at 2014-12-30 08:46 UTC using Safari 538.15 on Linux:

    Hi,

    I wasn’t able to get rvm to work with this solution … Maybe I did something wrong …

    In any case … I posted a different solution here:

    https://stackoverflow.com/questions/27380203/how-do-i-use-rvm-with-tcsh

    This doesn’t use bash and all, and is roughly similar to what the fish shell does…