August 09, 2013

Cron and Command line in Node.js

I found out that Macs don’t have cron, like in linux. They do have something similar called launchd, but I wanted to execute something as admin, and all sorts of stuff. Luckily, my favorite platform, node, has a cron and a command line to simulate a cron system.

First thing to get use to is the format. It is simple, but there are some things that you need to know about it. There is 6 fields, seperated by a space. Each field is a time slot, so first is second, minute, hour, day of month, month, day of the week. After that, you have to tell how each field should run, let’s check out the table below:

Symbol Meaning Example
\* Star means run on all options for that field i.e. \* \* \* \* \* \* – means run every second of every minute of every hour, and so on.
# Placing a number means to run it specifically for that field. i.e. 1 \* \* \* \* \* – means to run every minute, only on the first second.
, Placing a comma between numbers tells the cron job multiple runnings. i.e. 3,5,7,9 \* \* \* \* \* – means to run every minute, on the 3rd, 5th, 7th and 9th second. (so 4 times a minute)
A dash creates a range. i.e. 3-10 \* \* \* \* \* – means run on the 3rd, 4th, 5th, 6th, 7th, 8th, 9th, 10th second of every minute. (8 times)
/ Divide the section and run it every time it is divisable by that number. i.e. \*/10 \* \* \* \* \* – run every 10 seconds, \* \*/10 \* \* \* \* – run every 10 minutes

Those are the rules. There are more, but these are good enough to describe what timings you may need. Let’s check out some code then:

 var cronJob = require('cron').CronJob; new cronJob('\* \* \* \* \* \*', function(){ console.log('You will see this message every second'); }, null, true, "America/Los\_Angeles"); 

So that code is pretty simple, it runs every second and prints to console. Let’s now add some command line code:

 var obj = new Date(); var filename = obj.getFullYear()+"\_"+(obj.getMonth()+1)+"\_"+obj.getDate()+"\_"+obj.getHours()+"\_"+obj.getMinutes(); child = exec("redis-cli INFO > "+filename+".txt", function (error, stdout, stderr) { if(stderr){ sys.print('error: ' + stderr); } } ); }, function(){}, true); 

I have been working with redis, and needed to output command information to a text file, so I created this script to create log file from redis. Now, if we put all of this together:

 var sys = require('sys') var exec = require('child\_process').exec; var child; var cronJob = require('cron').CronJob; var a = new cronJob('0 0 \* \* \* \*', function(d){ var obj = new Date(); var val = obj.getFullYear()+"\_"+(obj.getMonth()+1)+"\_"+obj.getDate()+"\_"+obj.getHours()+"_"+obj.getMinutes(); child = exec("redis-cli INFO > "+val+".txt", function (error, stdout, stderr) { if(stderr){ sys.print('error: ' + stderr); } } ); }, function(){}, true); 

This code runs every first second, of the first minute, every hour, to log a text file from redis, with a file name based on the date time. Booooooooom!