Requiring a Ruby Gem in Ruby Script breaks Cron Job Execution - ruby

I'm trying to run a cron job using Gems. I've installed ruby via RVM and when I require a gem it breaks the cron job. I've tried requiring two totally different gems, PG / Pry, and when I require either, the cronjob doesn't complete. Here is the "testing code" that works fine:
open('/home/log.log', 'a') do |f|
f.puts Time.now.to_s
end
Here is how I setup the cronjob:
* * * * * /usr/local/rvm/rubies/ruby-2.0.0-p247/bin/ruby /home/test1.rb
I can see new output every minute. And when I add a require gem line at the top, it then breaks, but only when run through cron:
require 'pg'
open('/home/log.log', 'a') do |f|
f.puts Time.now.to_s
end
The cronjob runs (I can see it execute in the sys log), but never completes (no output ever makes it into the text file). I've tried this on two separate servers one Debian, one CentOS, and both have the same issue. Oddly enough this only affects the cron job, if I run the same ruby file from console: /home/test1.rb it will work just fine.
Any help would be great.

You need to setup your crontab with rvm e.g:
rvm cron setup
With that rvm sets your environment variables in your crontab file
then you have a crontab file having this at the top:
PATH="/usr/local/rvm/gems/ruby-1.9.3-p194/bin:/usr/local/rvm/gems/ruby-1.9.3-p194#global/bin:/usr/local/rvm/rubies/ruby-1.9.3-p194/bin:/usr/local/rvm/bin:/usr/local/rvm/gems/ruby-1.9.3-p194/bin:/usr/local/rvm/gems/ruby-1.9.3-p194#global/bin:/usr/local/rvm/rubies/ruby-1.9.3-p194/bin:/usr/local/rvm/bin:/usr/lib64/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/local/rvm/gems/ruby-1.9.3-p194#global/"
rvm_env_string='ruby-1.9.3-p194'
rvm_path='/usr/local/rvm'
rvm_ruby_string='ruby-1.9.3-p194'
RUBY_VERSION='ruby-1.9.3-p194'
GEM_HOME='/usr/local/rvm/gems/ruby-1.9.3-p194'
GEM_PATH='/usr/local/rvm/gems/ruby-1.9.3-p194:/usr/local/rvm/gems/ruby-1.9.3-p194#global'
MY_RUBY_HOME='/usr/local/rvm/rubies/ruby-1.9.3-p194'
IRBRC='/usr/local/rvm/rubies/ruby-1.9.3-p194/.irbrc'
Then you can stick your crontask beneath it

Related

Setting env variable to a cron scheduled task using whenever gem

In my code below, I wanted to set few environment variables stored in a file. Am I missing something? Printing env in production after 'bundle exec whenever' does not show the environment variables set. Using whenever gem for a scheduled cron task and spent hours figuring this. Any other way can be suggested too.
every 1.day, :at => '2:30 am' do
# Run shell script to assign variables and continue the rake task
system "for line in `cat config/myEnvFile.env` ; do export $line ; done"
rake "task:continue_doing_my_task"
end
system is not a whenever job type. It's Kernel.system, which executes the String being passed to it when the whenever command is run, rather than converting that String to cron syntax. It looks like what you really mean is:
command "for line in `cat config/myEnvFile.env` ; do export $line ; done"
# Note: command instead of system
command is a built-in job type defined by whenever here.
Each line of code inside the every-block runs as it's own command. If you run whenever (without any arguments, so it just displays what it would put in your crontab without actually modifying the crontab, and after making the correction I describe above), you'll see that the output is something like this:
30 2 * * * * /bin/bash -l -c 'for line in `cat config/myEnvFile.env` ; do export $line ; done'
30 2 * * * * /bin/bash -l -c 'cd /path/to/project && RAILS_ENV=production bundle exec rake task:continue_doing_my_task --silent > my_log_file.log 2&>1'
Notice 2 issues:
Firstly, these 2 commands have nothing to do with each other--they are run as 2 totally separate processes.
The first one is running in cron's default directory, which is probably not where config/myEnvFile.env is located.
To fix this, you need to merge everything into a single command. By using whenever's rake job type, you will end up in the right directory, but you still to export all those variables somehow.
One way to do this, is to rename the file .ruby-env and use rvm. rvm, in addition to managing ruby versions for you, will automatically load all environment variables defined in .ruby-env when you enter the directory.
If RVM is not an option for you, or you want something more lightweight, rename the file .env and use dotenv. Their README documents exactly how to use the gem, with or without Rails. Without Rails, it's this easy:
Add dotenv to your Gemfile
Make this change to your Rakefile:
require 'dotenv/tasks' # 1. require this file
namespace :task
task continue_doing_my_task: :dotenv do # 2. make :dotenv a prerequisite for your task

How can I automate a script [Ruby] to run at a given time every day?

I've written a webcrawler that pulls information into a report and would like to run it every day at 12:00pm. The script is run using:
ruby script.rb
I've tried using the whenever gem (https://github.com/javan/whenever).
My directory structure is this:
/config
schedule.rb
script.rb
In my script.rb file, I have the following:
every :day, :at => '12:00pm' do
command "ruby script.rb"
end
I've modified the time :at to take see if it runs and it doesn't.
I've also tried:
every :day, :at => '12:00pm' do
`ruby script.rb`
end
I've also looked into the "at" linux utility but it appears suited to one-time jobs. I'd like this to generate a report everyday.
Note: the script specifies where to output so I don't need to give it an output.
I've also tried creating a crontab but have encountered a problem with saving.
I use http://crontab-generator.org/ to generate the correct syntax.
Then I run:
crontab -e
Which opens vi and I copy the syntax. However, it exits with a status of 1 and if I run:
crontab -l
It says there's no jobs listed.
I've also tried running this as the super user, and it exits the same.
The error message is
/usr/bin/vi" exited with status 1
I just want a command to run at a given time, what am I missing?
Edit
Does it matter that I'm on a Mac?

Cron (hourly) task to execute a ruby script

I have a ruby script that I have tested to be working that I would like to run as an hourly cron but cannot seem to get it firing properly.
The last thing I have tried was placing the line:
ruby ~/ruby_script.rb
in /etc/cron.hourly
Said ruby script is located in the home directory with:
#!/usr/bin/env ruby
as its top line.
I have looked into ruby & cron resources but they most seem to be for reoccurring tasks in a Ruby on Rails environment when I just want the script to run in my ubuntu environment. I have double checked that rails is installed as well.
I have had a lot of fun learning more about ubuntu over the past few months and will truly appreciate any assistance I receive here. Thank you in advance.
Try to use current user crontab
$ crontab -e
Add new cron job
0 * * * * /bin/bash -l -c 'ruby ~/ruby_script.rb'
Using bash command to run helps to get env variables during script execution.
(for tests change 0 to * - script will try to run every minute)
To log errors you can try to add command:
0 * * * * /bin/bash -l -c 'ruby ~/ruby_script.rb >> ~/ruby_script.log 2>&1 &'
Hope it helps.

Ruby Cron job not running?

My cron job won't finish. And I've been spinning my wheels these past couple hours with no luck.
I have this line in my crontab:
* * * * * /usr/local/rvm/rubies/ruby-2.0.0-p195/bin/ruby /home/pra/grinder/misc_scripts/daily_total_logger.rb
I can run the command:
/usr/local/rvm/rubies/ruby-2.0.0-p195/bin/ruby /home/pra/grinder/misc_scripts/daily_total_logger.rb
and it works no problem.
I set it to run every minute so I can watch the logs and sure enough I see this in the logs (/var/log/cron):
Dec 19 01:32:01 hostname CROND[4574]: (root) CMD (/usr/local/rvm/rubies/ruby-2.0.0-p195/bin/ruby /home/pra/grinder/misc_scripts/daily_total_logger.rb)
I have replicated this same behavior on two separate servers (after fooling with the script for an hour I figured I'd just move it to another server, but same problem there).
I have tried one more thing. To create another ruby file with the same permissions that does something else (append the date time to a file). I created /home/pra/grinder/misc_scripts/test.rb with the following code
open('/home/log.log', 'a') do |f|
f.puts Time.now.to_s
end
And it works just fine. A quick check of the permissions shows that both files have idential permissions
-rw-r--r--. 1 root root 348 Dec 19 00:52 daily_total_logger.rb
-rw-r--r--. 1 root root 61 Dec 19 01:13 test.rb
I know it's best practice not to run this in root, I'm just trying to eliminate all potential issues. I can't for the life of me figure out what could be causing this. I simplified the script and I still have the same error with this super simple script:
require 'pg'
conn = PG.connect(dbname: '***',user: '***',password: '***', host: '***')
query = "INSERT INTO foobar (foo, bar) VALUES (1, 3)"
conn.exec(query)
puts "Done..."
And it works fine if I run it from the command line. Just won't complete if I run it as a cron job. I'm totally baffled - Same issue on two servers, one debian, one redhat... Any help would be highly appreciated.
I traced it down to this line:
require 'pg'
If I require that library in my script, the rest of the script stops running when called as a cron job, but works fine when called from the command line. For more information on this, I documented the problem a lot better here (and hopefully someone will shed light on why this is happening):
Requiring a Ruby Gem in Ruby Script breaks Cron Job Execution

Ruby daemon not working

I need to run a standalone ruby script as Unix (linux) daemon.
After running that daemon I need to run another Ruby method with it.
I installed the ruby-daemon gem on my machine by using the gem install daemon.
I did the test daemon program.
My test.rb file is :
module Test
def test_method
#s =" ITS WORKING !"
file=File.new("/home/username/test.txt", "w")
file.puts #s
file.close
end
end
My test_control.rb file is :
# this is myserver_control.rb
require 'rubygems' # if you use RubyGems
require 'daemons'
Daemons.run('test.rb')
After this I run the following command: ruby test_control.rb start
Now how can I check whether the daemon program has started properly?
How can I invoke a method with it?
Looks like the formatting on your post is way off, so hopefully someone can fix that, but I think the problem here is you're defining a module but not actually firing off the method you define.
The Daemons utility only executes the script provided. You should test that your "test.rb" file can be run on the command line directly before trying to diagnose what might be wrong with Daemons itself.
It may be as reworking test.rb:
module Test
def self.test_method
#s =" ITS WORKING !"
file = File.new("/home/username/test.txt", "w")
file.puts #s
file.close
end
end
Test.test_method
There are other ways to use Daemons where you pass it a module to run, but you're not using it that way.

Resources