A short tale of cron, rbenv and $PATH

Ever tried to use rbenv within a cronjob?

I have, and it was a bit of a struggle to get it up and running.

First of all cronjobs are not run in a login shell, and what that means is that your normal $HOME/.profile etc. startup scripts aren’t executed. So the first thing to do is starting a login shell that can run your job.

This is done with bash -l. Now you of course need to execute your job, so it has to be a non-interactive shell. Just do it like bash -lc "job".

So far, so good. This is similar to what you would do, if you’re using RVM.

Now when the cronjob is executed, what happens is that you’re told that bash doesn’t exist:

env: bash: No such file or directory

Which is strange, since it is no problem opening the login shell. What is making the job blow up then?

It happens to be the combination of $PATH and rbenv initialization, because of the call to rbenv init:

eval "$(rbenv init -)"

This is looking for bash in the $PATH, and if bash is in /usr/local/bin, you’re in troubles, since $PATH is quite restricted in cron - and therefore it doesn’t include /usr/local/bin.

So you need to add it to $PATH before opening the login shell.

The complete command to execute the job then becomes

PATH=$PATH:/usr/local/bin && bash -lc "job"