CrontabA module for reading, manipulating, and writing user cron jobs with node. Check out github for the source and installation guide. | |
| lib/index.js |
Constants
|
const COMMAND = '/usr/bin/crontab';
const ITEMREX = /^\s*([^@#\s]+)\s+([^@#\s]+)\s+([^@#\s]+)\s+([^@#\s]+)\s+([^@#\s]+)\s+([^#\n]*)(\s+#\s*([^\n]*)|$)/;
const SPECREX = /@(\w+)\s([^#\n]*)(\s+#\s*([^\n]*)|$)/;
const SPECIALS = {
'reboot' : '@reboot',
'hourly' : '0 * * * *',
'daily' : '0 0 * * *',
'weekly' : '0 0 * * 0',
'monthly' : '0 0 1 * *',
'yearly' : '0 0 1 1 *',
'annually' : '0 0 1 1 *',
'midnight' : '0 0 * * *'
};
const MONTH_ENUM = ['jan','feb','mar','apr','may','jun','jul','aug','sep','oct','nov','dec'];
const WEEK_ENUM = ['sun','mon','tue','wed','thu','fri','sat','sun'];
const SINFO = [
{ 'name' : 'Minute', 'max' : 59, 'min' : 0 },
{ 'name' : 'Hours', 'max' : 23, 'min' : 0 },
{ 'name' : 'Day of Month', 'max' : 31, 'min' : 1 },
{ 'name' : 'Month', 'max' : 12, 'min' : 1, 'enum' : MONTH_ENUM },
{ 'name' : 'Day of Week', 'max' : 7, 'min' : 0, 'enum' : WEEK_ENUM },
];
|
A JavaScript representation of a user crontab. Each tab has zero or more cron jobs coresponding
to the individual lines in the cron sytax.
Examples
new CronTab('bob', function(err, tab) {
if (err) { console.log(err); process.exit(1); }
console.log("bob's tab: " + tab.render());
});
new CronTab(function(err, tab) {
if (err) { console.log(err); process.exit(1); }
console.log("current user's tab: " + tab.render());
});
param: String username param: Function callback
|
function CronTab(u, cb) {
var self = this;
user = u || '',
root = (process.getuid() == 0),
backup = {lines:[], jobs:[]},
lines = [],
jobs = [];
load(cb);
|
Provides access to the jobs collection.
Examples
new CronTab(function(err, tab) {
if (err) { console.log(err); process.exit(1); }
var jobs = tab.getJobs();
for (var i = 0; i < jobs.length; i++) {
console.log(jobs[i].render());
}
});
|
this.getJobs = function() {
return jobs;
}
|
Writes the crontab to the system. Saves all information.
Examples
new CronTab(function(err, tab) {
if (err) { console.log(err); process.exit(1); }
var jobs = tab.findCommand('ls -l /');
tab.remove(jobs);
tab.save(function(err, tab) {
if (err) { console.log(err); process.exit(1); }
console.log('saved');
});
});
|
this.save = function(cb) {
var stdout = '',
stderr = '',
args = makeChildArgs('save'),
child = Spawn(COMMAND, args);
child.stdout.on('data', function(chunk) {
stdout += chunk;
});
child.stderr.on('data', function(chunk) {
stderr += chunk;
});
child.on('exit', function (code) {
if (code == 0) {
cb && cb(null, self);
}
else {
cb && cb({message:stderr}, self);
}
});
child.stdin.write(this.render());
child.stdin.end();
}
|
Renders the object to a string as it would be written to the system.
Examples
new CronTab(function(err, tab) {
if (err) { console.log(err); process.exit(1); }
console.log(tab.render());
});
|
this.render = function() {
var tokens = [];
for (var i = 0; i < lines.length; i++) {
var job = lines[i];
if (job.isValid && !job.isValid()) {
tokens.push('# ' + job.toString());
continue;
}
tokens.push(job.toString());
}
return tokens.join('\n').trim() + '\n';
}
|
Creates a new job with the specified command, comment and date.
Examples
new CronTab(function(err, tab) {
if (err) { console.log(err); process.exit(1); }
var future = Date.parse('2010/7/11');
tab.create('ls -l /');
tab.create('ls -l /', 'just a silly example');
tab.create('ls -l /', 'just a silly example', future);
});
param: String command param: String [comment] param: Date [date] return: CronJob | null
|
this.create = function(command) {
var args = Array.prototype.slice.call(arguments),
types = args.map(function(arg) { return typeof arg; }),
comment = (types[1] == 'string') ? args[1] : null,
job = makeJob(null, command, comment);
if (job == null) { return job; }
jobs.push(job);
lines.push(job);
var date = (args[1] instanceof Date) ?
args[1] : (args[2] instanceof Date) ?
args[2] :
null;
if (date && date instanceof Date) {
job.minute().on(date.getMinutes());
job.hour().on(date.getHours());
job.dom().on(date.getDate());
job.month().on(date.getMonth()+1);
}
return job;
}
|
Returns a list of jobs matching the specified command.
Examples
new CronTab(function(err, tab) {
if (err) { console.log(err); process.exit(1); }
var jobs = tab.findCommand('ls -l /');
for (var i = 0; i < jobs.length; i++) {
console.log(jobs[i].render());
}
});
|
this.findCommand = function(pattern) {
var results = [];
for (var i = 0; i < jobs.length; i++) {
var job = jobs[i];
if (job.command().match(pattern)) {
results.push(job);
}
}
return results;
}
|
Returns a list of jobs matching the specified inline comment.
Examples
new CronTab(function(err, tab) {
if (err) { console.log(err); process.exit(1); }
var jobs = tab.findComment('this should run every night');
for (var i = 0; i < jobs.length; i++) {
console.log(jobs[i].render());
}
});
|
this.findComment = function(pattern) {
var results = [];
for (var i = 0; i < jobs.length; i++) {
var job = jobs[i];
if (job.comment().match(pattern)) {
results.push(job);
}
}
return results;
}
|
Removes the specified jobs from the crontab.
Examples
new CronTab(function(err, tab) {
if (err) { console.log(err); process.exit(1); }
var jobs = tab.findCommand('ls -l /');
tab.remove(jobs);
});
|
this.remove = function(jobs) {
if (!(jobs instanceof CronJob) && !(jobs instanceof Array)) {
return;
}
if (jobs instanceof CronJob) {
jobs = [jobs];
}
for (var i = 0; i < jobs.length; i++) {
var job = jobs[i];
remove(job);
}
truncateLines();
}
|
Restores this crontab to its original state.
Examples
new CronTab(function(err, tab) {
if (err) { console.log(err); process.exit(1); }
var jobs = tab.findCommand('ls -l /');
tab.remove(jobs);
tab.reset();
});
|
this.reset = function() {
lines = backup.lines;
jobs = backup.jobs;
}
|
A JavaScript representation of a cron job. Each job has exactly 5 time slots as per cron sytax:
minute, hour, day-of-the-month, month, day-of-the-week.
Examples
var job1 = new CronJob('* * * * * ls -l / #comment');
var job2 = new CronJob(null, 'ls -l /', 'comment');
|
function CronJob(line, c, m) {
var self = this,
command = null,
comment = null,
valid = false,
slots = [],
special = false;
|
Returns true if this cron job is valid.
Examples
new CronTab(function(err, tab) {
if (err) { console.log(err); process.exit(1); }
var jobs = tab.findCommand('ls -l /');
for (var i = 0; i < jobs.length; i++) {
console.log(jobs[i].isValid());
}
});
|
this.isValid = function() {
return valid;
}
|
Renders the object to a string as it would be written to the system.
Examples
new CronTab(function(err, tab) {
if (err) { console.log(err); process.exit(1); }
var jobs = tab.findCommand('ls -l /');
for (var i = 0; i < jobs.length; i++) {
console.log(jobs[i].render());
}
});
|
this.render = function() {
var time = '';
if (special) {
time = special;
}
else {
var tokens = [];
for (var i = 0; i < 5; i++) {
tokens.push(slots[i].toString());
}
time = tokens.join(' ');
}
var keys = getKeys.call(SPECIALS),
vals = getVals.call(SPECIALS),
timeIdx = vals.indexOf(time);
if (timeIdx >=0 ) {
time = '@' + keys[timeIdx];
}
var result = time + ' ' + command.toString()
if (comment.toString() != '') {
result += ' #' + comment.toString();
}
return result;
}
|
Sets the cron job to every reboot instead of a time pattern.
Examples
new CronTab(function(err, tab) {
if (err) { console.log(err); process.exit(1); }
var command = '/usr/bin/env echo "starting some service..."';
jobs = tab.findCommand(command);
tab.remove(jobs);
var job = tabs.create(command);
job.everyReboot();
});
|
this.everyReboot = function() {
this.clear();
special = '@reboot';
}
|
Clears all time slots. Calling this method amounts to setting the time to ' *'.
Examples
new CronTab(function(err, tab) {
if (err) { console.log(err); process.exit(1); }
var jobs = tab.findCommand('ls -l /');
for (var i = 0; i < jobs.length; i++) {
console.log(jobs[i].clear());
}
});
|
this.clear = function() {
special = false;
for (var i = 0; i < slots.length; i++) {
slots[i].clear();
}
}
|
Returns the minute time slot.
Examples
new CronTab(function(err, tab) {
if (err) { console.log(err); process.exit(1); }
var jobs = tab.findCommand('ls -l /');
for (var i = 0; i < jobs.length; i++) {
console.log(jobs[i].minute().render());
}
});
|
this.minute = function() {
return slots[0];
}
|
Returns the hour time slot.
Examples
new CronTab(function(err, tab) {
if (err) { console.log(err); process.exit(1); }
var jobs = tab.findCommand('ls -l /');
for (var i = 0; i < jobs.length; i++) {
console.log(jobs[i].hour().render());
}
});
|
this.hour = function() {
return slots[1];
}
|
Returns the day-of-the-month time slot.
Examples
new CronTab(function(err, tab) {
if (err) { console.log(err); process.exit(1); }
var jobs = tab.findCommand('ls -l /');
for (var i = 0; i < jobs.length; i++) {
console.log(jobs[i].dom().render());
}
});
|
this.dom = function() {
return slots[2];
}
|
Returns the month time slot.
Examples
new CronTab(function(err, tab) {
if (err) { console.log(err); process.exit(1); }
var jobs = tab.findCommand('ls -l /');
for (var i = 0; i < jobs.length; i++) {
console.log(jobs[i].month().render());
}
});
|
this.month = function() {
return slots[3];
}
|
Returns the day-of-the-week time slot.
Examples
new CronTab(function(err, tab) {
if (err) { console.log(err); process.exit(1); }
var jobs = tab.findCommand('ls -l /');
for (var i = 0; i < jobs.length; i++) {
console.log(jobs[i].dow().render());
}
});
|
this.dow = function() {
return slots[4];
}
|
Command getter/setter.
Examples
new CronTab(function(err, tab) {
if (err) { console.log(err); process.exit(1); }
var jobs = tab.findCommand('ls -l /');
for (var i = 0; i < jobs.length; i++) {
console.log(jobs[i].command('new command'));
}
});
param: String [command] return: String
|
this.command = function(c) {
if (c) {
command = new CronCommand(c.toString());
}
return command.toString();
}
|
Comment getter/setter.
Examples
new CronTab(function(err, tab) {
if (err) { console.log(err); process.exit(1); }
var jobs = tab.findCommand('ls -l /');
for (var i = 0; i < jobs.length; i++) {
console.log(jobs[i].comment('new comment'));
}
});
param: String [comment] return: String
|
this.comment = function(c) {
if (c) {
comment = new CronComment(c.toString());
}
return comment.toString();
}
|
Renders the object to a string as it would be written to the system. See render.
Examples
new CronTab(function(err, tab) {
if (err) { console.log(err); process.exit(1); }
var jobs = tab.findCommand('ls -l /');
for (var i = 0; i < jobs.length; i++) {
console.log(jobs[i].toString());
}
});
|
this.toString = function() {
return this.render();
}
|
A JavaScript representation of a time slot (e.g. minute, hour, month). Each slot has zero or
more time ranges coresponding to the comma separated list in the cron sytax (e.g. * / 4, 10, 5-15/2).
Examples
var enum = ['jan','feb','mar','apr',
'may','jun','jul','aug',
'sep','oct','nov','dec'];
var slot1 = new TimeSlot('Month', 1, 12, enum);
var slot2 = new TimeSlot('Minute', 0, 59, null, '');
param: String name (e.g 'Minute', 'Month') param: Number min minimum value param: Number max maximum value param: Object | null enum an object enumerating all possible values param: String | null value a value to parse (e.g '19-0/2,0-3')
|
function TimeSlot(name, min, max, enum, value) {
var self = this,
name = name,
min = min,
max = max,
enum = enum,
parts = [];
|
Returns the minimum value for this time slot.
Examples
new CronTab(function(err, tab) {
if (err) { console.log(err); process.exit(1); }
var jobs = tab.findCommand('ls -l /');
for (var i = 0; i < jobs.length; i++) {
console.log(jobs[i].month().getMin());
}
});
|
this.getMin = function() {
return min;
}
|
Returns the maximum value for this time slot.
Examples
new CronTab(function(err, tab) {
if (err) { console.log(err); process.exit(1); }
var jobs = tab.findCommand('ls -l /');
for (var i = 0; i < jobs.length; i++) {
console.log(jobs[i].month().getMax());
}
});
|
this.getMax = function() {
return max;
}
|
Returns the allowed value enumeration for this time slot.
Examples
new CronTab(function(err, tab) {
if (err) { console.log(err); process.exit(1); }
var jobs = tab.findCommand('ls -l /');
for (var i = 0; i < jobs.length; i++) {
console.log(jobs[i].month().getEnum());
}
});
|
this.getEnum = function() {
return enum;
}
|
Renders the object to a string as it would be written to the system.
Examples
new CronTab(function(err, tab) {
if (err) { console.log(err); process.exit(1); }
var jobs = tab.findCommand('ls -l /');
for (var i = 0; i < jobs.length; i++) {
console.log(jobs[i].month().render());
}
});
|
this.render = function() {
return parts.map(function(part) {
return part.toString();
}).join(',') || '*';
}
|
Set this time slot to repeat every n units e.g. * / n
Examples
new CronTab(function(err, tab) {
if (err) { console.log(err); process.exit(1); }
var jobs = tab.findCommand('ls -l /');
for (var i = 0; i < jobs.length; i++) {
// every other month
jobs[i].month().every(2);
}
});
param: Number number return: TimeRange
|
this.every = function(n) {
try {
var range = new TimeRange(self, '*/' + parseInt(n));
parts.push(range);
return range;
}
catch (e) {}
return null;
}
|
Set this time slot to repeat exactly at the specified values e.g. 0,12
Examples
new CronTab(function(err, tab) {
if (err) { console.log(err); process.exit(1); }
var jobs = tab.findCommand('ls -l /');
for (var i = 0; i < jobs.length; i++) {
// at midnight and noon
jobs[i].hour().on(0, 12);
jobs[i].minute().on(0);
}
});
|
this.on = function() {
for (var i = 0; i < arguments.length; i++) {
parts.push(arguments[i]);
}
}
|
Set this time slot to repeat between from and to e.g. from - to
Examples
new CronTab(function(err, tab) {
if (err) { console.log(err); process.exit(1); }
var jobs = tab.findCommand('ls -l /');
for (var i = 0; i < jobs.length; i++) {
// business hours
jobs[i].hour().during(9, 17);
}
});
param: Number from param: Number to return: TimeRange
|
this.during = function(from, to) {
try {
var range = new TimeRange(self, from + '-' + to);
parts.push(range);
return range;
}
catch (e) {}
return null;
}
|
Clears this time slot. Calling this method amounts to setting the slot to '*'.
Examples
new CronTab(function(err, tab) {
if (err) { console.log(err); process.exit(1); }
var jobs = tab.findCommand('ls -l /');
for (var i = 0; i < jobs.length; i++) {
console.log(jobs[i].month().clear());
}
});
|
this.clear = function() {
parts = [];
}
|
Renders the object to a string as it would be written to the system. See render.
Examples
new CronTab(function(err, tab) {
if (err) { console.log(err); process.exit(1); }
var jobs = tab.findCommand('ls -l /');
for (var i = 0; i < jobs.length; i++) {
console.log(jobs[i].month().toString());
}
});
|
this.toString = function() {
return this.render();
}
|
A JavaScript representation of a time range. Each range has a from, to, and step values.
Examples
var enum = ['jan','feb','mar','apr',
'may','jun','jul','aug',
'sep','oct','nov','dec'];
var slot = new TimeSlot('Month', 1, 12, enum);
var range1 = new TimeRange(slot, '* / 2'); // every other month
var range2 = new TimeRange(slot, 'jun - sep'); // every summer
param: TimeSlot slot The owner time slot object param: String range The range string e.g. * / 2, jun - sep
|
function TimeRange(s, range) {
var self = this,
slot = s,
from = null,
to = null,
step = 1;
|
Renders the object to a string as it would be written to the system.
Examples
new CronTab(function(err, tab) {
if (err) { console.log(err); process.exit(1); }
var jobs = tab.findCommand('ls -l /');
for (var i = 0; i < jobs.length; i++) {
console.log(jobs[i].hour().during(9, 17).render());
}
});
|
this.render = function() {
var value = '*';
if (from > slot.getMin() || to < slot.getMax()) {
value = from + '-' + to;
}
if (step != 1) {
value += '/' + step;
}
return value;
}
|
Set the step value for this range.
Examples
new CronTab(function(err, tab) {
if (err) { console.log(err); process.exit(1); }
var jobs = tab.findCommand('ls -l /');
for (var i = 0; i < jobs.length; i++) {
// every other business hour
jobs[i].hour().during(9, 17).every(2);
}
});
|
this.every = function(value) {
step = parseInt(value);
}
|
Renders the object to a string as it would be written to the system. See render.
Examples
new CronTab(function(err, tab) {
if (err) { console.log(err); process.exit(1); }
var jobs = tab.findCommand('ls -l /');
for (var i = 0; i < jobs.length; i++) {
console.log(jobs[i].hour().during(9, 17).toString());
}
});
|
this.toString = function() {
return this.render();
}
|
A JavaScript representation of the command part of a cron job.
Examples
var command = new CronCommand('ls -l /');
|
function CronCommand(line) {
var command = line;
|
Returns true if the pattern that was passed matches this command.
Examples
new CronTab(function(err, tab) {
if (err) { console.log(err); process.exit(1); }
var jobs = tab.findCommand('ls -l /');
for (var i = 0; i < jobs.length; i++) {
// true
console.log(jobs[i].command().match('ls -l /'));
}
});
|
this.match = function(pattern) {
if ((pattern instanceof String) == true && command.indexOf(pattern) >= 0) {
return true;
}
if ((pattern instanceof RegEx) == true) {
return pattern.test(command);
}
return false;
}
|
Renders the object to a string as it would be written to the system.
Examples
new CronTab(function(err, tab) {
if (err) { console.log(err); process.exit(1); }
var jobs = tab.findCommand('ls -l /');
for (var i = 0; i < jobs.length; i++) {
console.log(jobs[i].command().toString());
}
});
|
this.toString = function() {
return command;
}
}
|
A JavaScript representation of the inline comment part of a cron job.
Examples
var comment = new CronComment('run this on the weekend');
|
function CronComment(line) {
var comment = line;
|
Returns true if the pattern that was passed matches this comment.
Examples
new CronTab(function(err, tab) {
if (err) { console.log(err); process.exit(1); }
var jobs = tab.findComment('run this on the weekend');
for (var i = 0; i < jobs.length; i++) {
// true
console.log(jobs[i].comment().match('run this on the weekend'));
}
});
|
this.match = function(pattern) {
if ((pattern instanceof String) == true && comment.indexOf(pattern) >= 0) {
return true;
}
if ((pattern instanceof RegEx) == true) {
return pattern.test(comment);
}
return false;
}
|
Renders the object to a string as it would be written to the system.
Examples
new CronTab(function(err, tab) {
if (err) { console.log(err); process.exit(1); }
var jobs = tab.findComment('run this on the weekend');
for (var i = 0; i < jobs.length; i++) {
console.log(jobs[i].comment().toString());
}
});
|
this.toString = function() {
return comment;
}
}
|