Why does this node.js script not run in crontab? - node.js

If I run my node.js script in the containing directory, it runs fine. If I run it from crontab with
*/1 * * * * /usr/local/bin/node /Users/full/path/to/main >> ~/mtf.log
I see errors relating to the twilio config
var TWClient = require('twilio')(configTwilio.accountSid, configTwilio.
^
TypeError: Cannot read property 'accountSid' of undefined
Why doesn't this work when run from cron? The same behaviour occurs on the server (ubuntu) and localhost (OSX 10.8.5)
Top of script (main.js)
var phantom = require('phantom');
var portscanner = require('portscanner');
var FeedParser = require('feedparser'),
request = require('request');
var configDB = require('config').DB;
var configTwilio = require('config').Twilio;
var mysql = require('mysql');
var TWClient = require('twilio')(configTwilio.accountSid, configTwilio.authToken);
The config file default.yaml is in the config directory relative to main.js and contains (redacted):
DB:
dbHost: localhost
dbPort: 3306
dbName: xxx
dbUser: xxx
dbPass: xxx
Twilio:
accountSid: AC8fxxxxxxxxd5f7aace47a8
authToken: d863b4ddfxxxxxx9b7c845
I've also tried this locally:
env -i sh -c 'cd /path/to/script && /usr/local/bin/node main'
but get:
events.js:72
throw er; // Unhandled 'error' event
^
Error: spawn ENOENT

If you try wrapping it inside a shell script, you may have success with setting some environment variables in the crontab entry.
See this answer to a similar question:
https://stackoverflow.com/a/27823675/608269

When you schedule a cron task, the node js won't identify the config json files in your local directory. Add the code below in your main.js file to change the node config directory.
process.env.NODE_CONFIG_DIR= __dirname +'/config';
var config = require('config');

Related

Access $HOME variable from node js child_process?

It seems like I can't access the $HOME property within my nodeJS app when running a child_process on my Linux machine:
var exec = require('child_process').exec
var testHome = `echo $HOME`
testHomeCmd = exec(testHome)
testHomeCmd.stdout.on('data', function (data) {
console.log(data)
})
Where the output I receive is: [17597]: /
If I run echo $HOME in terminal I receive:
$ echo $HOME
/home/cs4
Any thoughts?

Cannot get argument with Commanderjs

I'm trying to pass a command line argument through node like so: npm start -s config.yml, where npm start maps to node app.js in my package.json.
app.js is as follows:
const program = require('commander');
console.log(process.argv);
program
.command('-s, --shell <value>', '.yml config file')
.parse(process.argv);
console.log(program.shell);
the argument is being passed through process.argv, but when I log program.shell it comes back undefined. What am I doing wrong?
Running the following:
$ node runme.js shell aceofspades
On the following file:
// FILE: runme.js
const program = require('commander');
program
.command('shell [value]', '.yml config file')
.action((cmd, opt) => {
console.log('cmd:', cmd); // shell
console.log('opt:', opt); // aceofspades
});
program.parse(process.argv);
Gives me the command and arguments within the action function for the command.

Trouble writing a file with CronJob in Heroku using writeFileSync()

I am trying to repeatedly update a file using a cronjob. Eventually, this is going to be more complicated but for now I'm trying to figure out my current problem. I know the code below is somewhat over-complicated because I preserved the basic structure while trying to problem solve. Here is the server file:
// server.js
var express = require('express');
var port = process.env.PORT || 8080;
var http = require('http');
var fs = require("fs");
var curtainup = require('./diagnoseleak.js');
var url = require("url" );
var app = express();
// launch ======================================================================
app.listen(port);
//run the CronJob
var CronJob = require('cron').CronJob;
new CronJob('0 * * * * *', function() {
console.log("running");
var date = new Date();
console.log("Ran at: "+date.getHours()+":"+date.getMinutes());
curtainup.doitnow();
} , null, true, 'America/New_York');
And here is the file referenced called diagnoseleak.js:
var fs = require("fs");
var mostRecentLocation = "./config/pullfiles/mostRecent55.txt";
module.exports = {
doitnow: function(){
var writethefile = function(){
fs.writeFileSync(mostRecentLocation, "A file called mostRecent55 should be create with this text", { flag: 'w' });
console.log("This should write to the console");
}
writethefile();
}
}
From the directory that houses the server file, I type the following into cmd:
git add .
git commit -m "adding files"
git push heroku master
heroku run bash
Then into the bash window I type:
cd config/pullfiles
ls -l
AND...no file called mostRecent55.txt appears. Am I looking in the wrong place? Eventually I want to be able to update a file, but I have a feeling I'm either looking in the wrong place for this mostRecet55.txt file or going about the process of writing it incorrectly.
heroku doesn't let you write files onto the filesystem where your app is stored. You would need to use an add-on, database or external service of some kind. The only exception seems to be /tmp which is only temporary storage

Spawning child_process in NodeJS with valid HOME folder set

I'm trying to spawn a process in NodeJS that accesses the my home folder, and can't see, to get either of the options below to work.
var spawn = require('child_process').spawn,
options = {stdio: 'inherit', env: process.env};
spawn('ls', ['~/'], options);
spawn('ls', ['$HOME'], options);
Output
ls: ~/: No such file or directory
ls: $HOME: No such file or directory
I've verified that options.env.HOME is properly set, any idea what I'm doing wrong?
Update
So this is what I ended up doing to make my use-case work (using script instead of ls):
spawn('script', [process.env.HOME], options);
Then, inside of my script:
#!/usr/bin/env bash
export HOME=$1
I still don't understand why options.env.HOME does not seem to work as expected.
process.env.HOME is what you want. Use it like so:
var spawn = require('child_process').spawn,
options = {stdio: 'inherit'};
var ls = spawn('ls', [process.env.HOME]);
ls.stdout.on('data', function(data){
console.log(String(data));
});
ls.stderr.on('data', function(data){
console.log(String(data));
});
Then you can set HOME in your shell when invoking the node script:
HOME='/tmp'; node ls.js
Alternatively, you don't have to overload HOME. To use whatever variable you like export it first, and then access it through process.env.:
export FOO='/tmp'; node ls.js

NODE JS - Forever starting path problems

I have a server.js file defined as follows:
var iniparser = require('iniparser');
var inihost;
var inidbuser;
var inidbpass;
var inidbname;
var config = iniparser.parseSync('../setup_db/config.ini');
inihost = config.db_hostname;
inidbuser=config.db_username;
inidbpass=config.db_password;
inidbname=config.db_name;
.....
on reboot I have a crontab that should automatically forever starts the server:
#reboot /usr/bin/sudo /usr/local/bin/forever start /var/www/html/rubrica/chat/server.js
Interestingly if I launch the server from any directory with the complete path like:
forever start /var/www/html/rubrica/chat/server.js
the server starts just fine..if , however, i run the SAME command from withtin the /root/.forever/ directory the server will give me the following error:
ENOENT, no such file or directory '../setup_db/config.ini'
So whenever i reboot the machine I get that error...how is such a thing possible?
The argument to iniparser.parseSync() is not relative to the current file like require() but rather the current working directory. Use:
var path = require('path');
var config = iniparser.parseSync(path.join(__dirname, '../setup_db/config.ini'));

Resources