Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Need to set up rvm environment prior to every cron job

Tags:

cron

rvm

crontab

I installed and configured RVM roughly following the pattern outlined in the first part of this set of instructions: http://blog.ninjahideout.com/posts/a-guide-to-a-nginx-passenger-and-rvm-server

Basically, this means there is no pre-build system ruby (all ruby installs are RVM-managed) and RVM is installed system-wide instead of attached to a particular user (files at /usr/local/rvm) so all users in the rvm group can access the same rubies with the same installed gems.

One issue with setting up the system this way is that the rvm environment must be set up in a shell session before ruby can be used. For all rvm users, I put this in their .bashrc: source "/usr/local/rvm/scripts/rvm". This works fine for ssh sessions.

The problem comes in play for cron jobs, which don't execute .bashrc. The rvm script above (/usr/local/rvm/scripts/rvm) is considerably more complicated than setting up a few environment variables, so I'd actually like to run this command prior to every job in the file.

Sure, I could do that manually, like so:

1 2 * * * source "/usr/local/rvm/scripts/rvm"; /do/some/cron/job/1
3 4 * * * source "/usr/local/rvm/scripts/rvm"; /do/some/cron/job/2
5 6 * * * source "/usr/local/rvm/scripts/rvm"; /do/some/cron/job/3
7 8 * * * source "/usr/local/rvm/scripts/rvm"; /do/some/cron/job/4

But I'd prefer to do something like this:

[execute] source "/usr/local/rvm/scripts/rvm"

1 2 * * * /do/some/cron/job/1
3 4 * * * /do/some/cron/job/2
5 6 * * * /do/some/cron/job/3
7 8 * * * /do/some/cron/job/4

Obviously, the above syntax doesn't work. But, is there some way to get this to work? The cron man pages and documentation were not of much help here. But is there some trick or standard way to achieve this?

If it matters, I'm running Ubuntu 10.10 (Maverick Meerkat).

like image 352
Ben Lee Avatar asked Apr 15 '11 17:04

Ben Lee


People also ask

Can cron read environment variables?

As of 12.04, variables in /etc/environment are loaded for cron. Best answer, just execute env >> /etc/environment and all the current env vars are now available in the CRON jobs.

Does crontab need to be executable?

crontab files have to be regular files or symlinks to regular files, they must not be executable or writable for anyone else but the owner. This requirement can be overridden by using the -p option on the crond command line.


2 Answers

Just do rvm cron setup

This let's rvm setup ruby cron settings

Then crontab -e

Add your cron tasks, save and close and you are good to go!!

like image 108
Mutuma Avatar answered Oct 29 '22 04:10

Mutuma


You don't need to write wrappers (following that logic, you might as well write a wrapper to the wrapper). Please keep things simple. All you need to do is configure your cron job to launch a bash shell, and make that bash shell load your environment.

The shebang line in your script should not refer directly to a ruby executable, but to rvm's ruby:

#!/usr/bin/env ruby

This instructs the script to load the environment and run ruby as we would on the command line with rvm loaded.

On many UNIX derived systems, crontabs can have a configuration section before the actual lines that define the jobs to be run. If this is the case, you would then specify:

SHELL=/path/to/bash  

This will ensure that the cron job will be spawned from bash. Still, your environment is missing, so to instruct bash to load your environment, you will want to add to the configuration section the following:

BASH_ENV=/path/to/environment (typically .bash_profile or .bashrc) 

HOME is automatically derived from the /etc/passwd line of the crontab owner, but you can override it.

HOME=/path/to/home

After this, a cron job might look like this:

15 14 1 * *     $HOME/rvm_script.rb

What if your crontab doesn't support the configuration section? Well, you will have to give all the environment directives in one line, with the job itself. For example,

15 14 1 * * export BASH_ENV=/path/to/environment && /full/path/to/bash -c '/full/path/to/rvm_script.rb'

Full blog post on the subject

like image 21
Daniel Szmulewicz Avatar answered Oct 29 '22 04:10

Daniel Szmulewicz