I'm trying to run a ruby script using rbenv with cron. I know that I need to load rbenv in order to have the right ruby version loaded.
I've tried options like this :
*/10 * * * * /bin/bash -c 'source $HOME/.bashrc; cd /data/app; ruby -v' >> /tmp/logfile.txt 2>&1
but as the session is not interactive, I'm not having the right ruby version. I've found example like this :
15 14 1 * * export BASH_ENV=/path/to/environment && /full/path/to/bash -c '/full/path/to/rvm_script.rb'
It didn't work neighter. Then I wrote a loader, which only load rbenv in the current shell but it doesn't work.
*/1 * * * * /bin/bash -c '$HOME/.rbenv/loader.sh ; cd /data/app/; ruby -v ' >> /tmp/logfile.txt 2>&1
Now I'm searching another way to load it ... any idea ?
I've found a solution to load rbenv. Either with a loader importing rbenv to the PATH :
*/1 * * * * /bin/bash -c '. $HOME/.rbenv/loader.sh ; cd /data/app/; ruby -v'
The '.' before '$HOME/.rbenv/loader.sh' is important, it runs the script in the current shell
Or without loader, which is better :
*/1 * * * * /bin/bash -c 'export PATH="$HOME/.rbenv/bin:$PATH" ; eval "$(rbenv init -)"; cd /data/app/; ruby -v'
A better solution is to simply use the command bash -lc
command. This will read your bash profile file, which would setup rbenv. From the bash
man page:
-l Make bash act as if it had been invoked as a login shell
When bash is invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first reads and executes commands from the file /etc/profile, if that file exists. After reading that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes commands from the first one that exists and is readable. The --noprofile option may be used when the shell is started to inhibit this behavior.
Even though kmmndr's answer is correct, I also like the bash -l
-approach.
Opening a non-interactive login shell keeps things simpler and since my Rails applications and Ruby scripts all run under the same user, overhead is not a problem.
So instead of
*/1 * * * * /bin/bash -c 'export PATH="$HOME/.rbenv/bin:$PATH" ; eval "$(rbenv init -)"; cd /data/app/; ruby -v'
I do
*/1 * * * * /bin/bash -lc 'cd /data/app/; ruby -v'
As noted in the above answer, bash -l
will act as if you login normally, which means that your rbenv environment will already be set up (as long as you have the appropriate lines in your .bashrc
, .bash_profile
of /etc/profile.d/*
).
If you need more detail, I wrote a blog post about this topic.
For my backup script in Ruby I simply use ~/.rbenv/bin/rbenv exec ruby [options] /path/to/ruby/script.rb
. Try this:
* * * * * ~/.rbenv/bin/rbenv exec ruby -v > ~/rbenv-ruby-version.txt
This answer from @Kelvin worked for me:
*/1 * * * * PATH=$HOME/.rbenv/bin:$HOME/.rbenv/shims:$PATH ruby -v >> ~/test.out
来源:https://stackoverflow.com/questions/8434922/ruby-script-using-rbenv-in-cron