1

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

1 Answers1

1
  1. 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.

  2. 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:

    1. Firstly, these 2 commands have nothing to do with each other--they are run as 2 totally separate processes.

    2. 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
      
Isaac Betesh
  • 2,935
  • 28
  • 37