After realizing that the sympal_scripts were silently failing to properly call cron.php on sites served from subdirectories on a shared Drupal multisite instance, I rolled up my sleeves to build a script that actually worked. What I’ve come up with works, but is likely not the cleanest or most efficient way of doing things. But it works. Which is better than the solution I had earlier today.

I also took the chance to get more familiar with Ruby. I could have come up with a shell script solution, but I wanted the flexibility to more easily extend the script as needed. And I wanted the chance to play with Ruby in a non-Hello-World scenario.

Here’s the code:

#!/usr/local/bin/ruby

# Drupal multisite hosting auto cron.php runner
# Initial draft version by D'Arcy Norman dnorman@darcynorman.net
# URL goes here
# Idea and some code from a handy page by (some unidentified guy) at http://whytheluckystiff.net/articles/wearingRubySlippersToWork.html

require 'net/http'

# this script assumes that $base_url has been properly set in each site's settings.php file.
# further, it assumes that it is at the START of a line, with spacing as follows:
# $base_url = 'http://mywonderfuldrupalserver.com/site';
# also further, it assumes there is no comment before nor after the content of that line.

# customize this variable to point to your Drupal directory
drupalsitesdir = '/usr/www/drupal' # no trailing slash

Dir[drupalsitesdir + '/sites/**/*.php'].each do |path|
  File.open(path) do |f|
    f.grep( /^\$base_url = / ) do |line|
      line = line.strip();
      baseurl = line.gsub('$base_url = \'', '')
      baseurl = baseurl.gsub('\';', '')
      baseurl = baseurl.gsub('  // NO trailing slash!', '')

      if !baseurl.empty?
        cronurl = baseurl + "/cron.php"
        puts cronurl

        if !cronurl.empty?
          url = URI.parse(cronurl)
          req = Net::HTTP::Get.new(url.path)
          res = Net::HTTP.start(url.host, url.port) {|http|http.request(req)}
          puts res.body
        end
      end
    end
  end
end

No warranty, no guarantee. It works on my servers, and on my PowerBook.

Some caveats:

  • It requires a version of Ruby more recent than what ships on MacOSX 10.3 server. Easy enough to update, following the Ruby on Rails installation instructions.
  • It requires $base_url to be set in the settings.php file for each site you want to run cron.php on automatically.
  • It requires one trivial edit to the script, telling it where Drupal lives on your machine. I might take a look at parameterizing this so it could be run more flexibily.
  • It requires cron (or something similar) to trigger the script on a regular basis.

Comments

4 Responses to “Script for running Cron on all sites in a shared Drupal instance”

  1. Khalid on January 2nd, 2007 10:39 am

    Darcy,

    Ruby may not be available on all systems.

    Here is a shell script that does the same thing. Same assumptions as yours. It is tested too.

    #!/bin/sh
    
    if [ $# = 1 ]; then
      DRUPAL_SITES_DIR=$1/sites
      if [ -d "$DRUPAL_SITES_DIR" ]; then
        cd $DRUPAL_SITES_DIR
    
        for SITE in `ls -F | grep /`
        do
          FILE=${SITE}settings.php
          if [ -r "$FILE" ]; then
            URL=`grep '^\$base_url.*=' $FILE | sed -e "s/^.*http://" -e "s/[';]//g"`
            if [ "$URL" != "" ]; then
              wget -O - -q http:$URL/cron.php
            fi
          fi
        done
      fi
    fi
    
  2. dnorman on January 2nd, 2007 12:00 pm

    Khalid - Well, fine then. Go ahead and whip up a better, more generalizable script that will run anywhere. :-)

    At least I got to play in Ruby for a bit. I’ll be switching to your script to run cron.php, though. Thanks!

  3. sami khan on January 2nd, 2007 2:32 pm

    lol. i was thinking, c’mon now d’arcy a ruby script to power a php script?!?

  4. dnorman on January 2nd, 2007 2:44 pm

    yeah yeah… I could have written it in C, so I could run ./configure make make install too :-) I just wanted to write the script and figured Ruby would be cool. Loosely joined and all that. It’s just firing off a curl to a web interface anyway. It could have been written in Logo :-)

Leave a Reply




Readers who viewed this page, also viewed:

  • N/A
Creative Commons License
This work is licensed under a Creative Commons Attribution 2.5 Canada License.