MacOS – How to create automatic launchd job that sets the Ruby version to use

launchdmacosruby

I’d like to run a ruby script automatically once or twice a day on my MacBook running OS X Yosemite.

Problem is that I currently have three versions of Ruby on my system including 1.8.7 and 2.2.1, neither of which the script will run with. So I say rvm use system which switches to a different version, though I don’t know how to find out which one (as rvm current just replies “system”). And then I can run the script happily.

However, when I create this little script:

#!/bin/bash
rvm use system
/Users/jonathan/Library/Scripts/slogger/slogger

It won’t run from the shell, saying:

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.

I know how to create and set basic launchd jobs; but I don’t know how to set the ruby version for the created process if I can’t include it in a script in this way. I’m sure it must be possible, though…

Best Answer

This is untested (as I don’t use rvm), but there should be two simple ways to fix this.

  1. Source rvm in your script (which you likely do anyway in your .profile, or .bashrc, or equivalent):

    #!/bin/bash
    [[ -s "${HOME}/.rvm/scripts/rvm" ]] && source "${HOME}/.rvm/scripts/rvm"
    rvm use system
    /Users/jonathan/Library/Scripts/slogger/slogger
    

    That new line is a shorter way of saying

    if [[ -s "${HOME}/.rvm/scripts/rvm" ]]; then
      source "${HOME}/.rvm/scripts/rvm"
    fi
    

    -s is used to return “True if FILE exists and has a size greater than zero”.

  2. And you’ll probably laugh as to how easy it was to fix, simply do what the message says and use /bin/bash --login, like so:

    #!/bin/bash --login
    rvm use system
    /Users/jonathan/Library/Scripts/slogger/slogger