NodeJS exec() command for both Windows and Ubuntu - node.js

Using NodeJS, NPM, and Gulp.
I want to build a gulp task to run JSDoc that works on Ubuntu and Windows.
This works on Ubuntu...
var exec = require('child_process').exec;
return function(cb) {
exec('node node_modules/.bin/jsdoc -c jsdoc-conf.json', function(err, stdout, stderr) {
cb(err);
});
};
And this works on Windows...
var exec = require('child_process').exec;
return function(cb) {
exec('node_modules\\.bin\\jsdoc -c jsdoc-conf.json', function(err, stdout, stderr) {
cb(err);
});
};
Needless to say, neither works on the other. How do others solve this type of problem?

Try using path.resolve, which should provide you with a full path to the file regardless of the platform.

Node has process.platform, which... "returns a string identifying the operating system platform on which the Node.js process is running. For instance darwin, freebsd, linux, sunos or win32"
https://nodejs.org/api/process.html#process_process_platform
var exec = require('child_process').exec;
return function(cb) {
if (process.platform === 'win32') {
// Windows OS
} else {
// everything else
}
};

Using path.resolve:
const exec = require('child_process').exec;
const path = require('path');
return function(cb) {
let command = `node ${path.resolve('node_modules/.bin/jsdoc')} -c jsdoc-conf.json`;
exec(command, function(err, stdout, stderr) {
cb(err);
});
};

Related

Run Bash-Script within Electron App using child_process.exec

I'm struggling with running a bash-script within main.html.
const exec = require("child_process").exec;
// Execute bash script
exec("/c/workspace/_edu_zone/Proxy_Manager/filemover.sh", shellCallback);
// Callback
function shellCallback(error, stdout, stderr) {
console.log(error, stdout)
}
I'm always getting the error: no such file or directory. What am i doing wrong?
Any help is highly appreciated.
change
/c/workspace/_edu_zone/Proxy_Manager/filemover.sh
to
c:/workspace/_edu_zone/Proxy_Manager/filemover.sh
or
your could try using node-powershell to execute the command directly
const shell = require('node-powershell')
let ps = new shell({
executionPolicy: 'Bypass',
noProfile: true
});
function lunchnode() {
process.stdout.write('logging');
ps.addCommand('node run.js')
ps.invoke()
.then(function (output) {
process.stdout.write(output)
}).catch(function (err) {
process.stdout.write(err)
ps.dispose()
})
}

Relative path does not work in child_process / node

Below is the current code I use in a Gulp task to run a bat file. The path is absolute.
var gulp = require('gulp');
var exec = require('child_process').exec;
module.exports = function() {
// Merges the CSS and JS files
return exec("C:/git/xxxx/Config/BuildScripts/buildassets.bat",
function (err, stdout, stderr) {
console.log(stdout);
console.log(stderr);
}
);
};
I want to make it as relative path, but when I change it to a relative path,
return exec('../../../Config/BuildScripts/buildassets.bat'
I get the following error:
'..' is not recognized as an internal or external command,
operable program or batch file.
How can I reference this file relatively?
I am doing this for that purpose but in my main process not in gulp file.
const app = electron.app;
const exec = require('child_process').exec;
var path = app.getAppPath();
exec(`"${path}\\path\\toexe.exe"`, function (err, stdout, stderr) {
console.log(stdout);
console.log(stderr);
});
Instead of using /, use \\:
return exec('..\\..\\..\\Config\\BuildScripts\\buildassets.bat', function() {
...
})

I want to run npm install and grunt in the background

So I have code in node, I want to run npm install and grunt in the background. npm install should run before grunt runs. Both both should run in the asynchronously. How can I get this done using node?
Shelling out the commands from within node, it will look like this:
const exec = require('child_process').exec;
exec('npm install && grunt', (err, stdout, stderr) => {
if (err) {
console.error(err);
return;
}
console.log(stdout);
});
If you want to run both as described, in the background from you shell just run
npm install && grunt &
To write the output to a file, you could do
const exec = require('child_process').exec;
exec('npm install && grunt', (err, stdout, stderr) => {
fs.writeFile('outputOfNpmInstallPlusGrunt.txt', stdout, () => { ... })
}
Conversely, using spawn this would look something like:
const spawn = require('child_process').spawn;
function makeRunner(name, cb) {
var ls = spawn(name, []);
var output = '';
ls.stdout.on('data', (data) => { output += data; });
ls.on('close', (code) => {
fs.writeFile(name.split(' ').join('-'), output, cb);
});
}
makeRunner('npm install', () => makeRunner('grunt'));

Using Gulp to manage opening and closing MongoDB

So far I have a child_process that executes 'mongod --dbpath db' and another child_process which can kill it with 'mongod --dbpath db --shutdown'. How do I listen for the user to enter ctrl-c or exit the gulp runner, and then run the gulp task to shutdown mongo?
I was trying something similar and came across this answer. I refactored it a little to just be the run command function. Functionally there should be no difference between --shutdown and the command I'm using.
var gulp = require('gulp');
var exec = require('child_process').exec;
function runCommand(command) {
return function (cb) {
exec(command, function (err, stdout, stderr) {
console.log(stdout);
console.log(stderr);
cb(err);
});
}
}
//Running mongo
//https://stackoverflow.com/a/28048696/46810
gulp.task('start-mongo', runCommand('mongod --dbpath ./data/'));
gulp.task('stop-mongo', runCommand('mongo --eval "use admin; db.shutdownServer();"'));
gulp.task('start-app', runCommand('node app.js'));
#QueueHammer's response was very helpful, but to get this running for my particulars (OSX, MongoDB 3.0.1) it took the following:
var exec = require('child_process').exec;
var mkdirs = require('mkdirs');
var runCommand = function(command) {
exec(command, function (err, stdout, stderr) {
console.log(stdout);
console.log(stderr);
if (err !== null) {
console.log('exec error: ' + err);
}
});
}
gulp.task("mongo-start", function() {
var command = "mongod --fork --dbpath "+paths.dbDir+"/ --logpath "+paths.dbLogs+"/mongo.log";
mkdirs(paths.dbDir);
mkdirs(paths.dbLogs);
runCommand(command);
});
gulp.task("mongo-stop", function() {
var command = 'mongo admin --eval "db.shutdownServer();"'
runCommand(command);
});
To further add on to the above answers, if you'd like a platform-independent solution that works in any OS/environment. You can use docker.
So you're gulp task would be something like:
const Gulp = require('gulp');
const exec = require('child_process').exec;
function runCommand(command) {
return function (cb) {
exec(command, function (err, stdout, stderr) {
console.log(stdout);
console.log(stderr);
cb(err);
});
};
}
// Database tasks
Gulp.task('start-mongo', runCommand('docker run --rm --name mongo-dev -p 27017:27017 mongo'));
Gulp.task('start-mongo-viewer', runCommand('docker run --rm --name mongo-express-dev --link mongo-dev:mongo -p 8081:8081 mongo-express'));

(Node.js) How to store stdout.pipe into a variable?

I want to get free -m (linux shell command) and store its result into a variable
by using source code below:
var spawn = require('child_process').spawn,
command = spawn('free', ['-m']);
command.stdout.pipe(process.stdout);
Is there any way to store process.stdout in a variable, please me some suggestions
This is fairly simple with child_process.exec:
var child = require("child_process");
var freeOut;
child.exec("free", ["-m"], function (error, stdout, stderr) {
if (error) {
console.error(error, stderr);
return;
}
//stdout and stderr are available here
freeOut = stdout;
process.stdout.write(stdout);
});
//Note. Do NOT use freeOut here. exec is async. Can only use in the callback

Resources