90 lines
1.9 KiB
JavaScript
90 lines
1.9 KiB
JavaScript
|
var
|
||
|
cp = require("child_process"),
|
||
|
merge = require("merge");
|
||
|
|
||
|
var
|
||
|
sh, cmd,
|
||
|
defSpawnOptions = { stdio: "inherit" };
|
||
|
|
||
|
/**
|
||
|
* @summary Get shell program meta for current platform
|
||
|
* @private
|
||
|
* @returns {Object}
|
||
|
*/
|
||
|
function getShell(){
|
||
|
if (process.platform === "win32") {
|
||
|
return { cmd: "cmd", arg: "/C" };
|
||
|
} else {
|
||
|
return { cmd: "sh", arg: "-c" };
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Callback is called with the output when the process terminates. Output is
|
||
|
* available when true is passed as options argument or stdio: null set
|
||
|
* within given options.
|
||
|
*
|
||
|
* @summary Execute shell command forwarding all stdio
|
||
|
* @param {String|Array} command
|
||
|
* @param {Object|TRUE} [options] spawn() options or TRUE to set stdio: null
|
||
|
* @param {Function} [callback]
|
||
|
* @returns {ChildProcess}
|
||
|
*/
|
||
|
function execSh(command, options, callback){
|
||
|
if (Array.isArray(command)) {
|
||
|
command = command.join(";");
|
||
|
}
|
||
|
|
||
|
if (options === true) {
|
||
|
options = { stdio: null };
|
||
|
}
|
||
|
|
||
|
if (typeof options === "function") {
|
||
|
callback = options;
|
||
|
options = defSpawnOptions;
|
||
|
} else {
|
||
|
options = options || {};
|
||
|
options = merge(true, defSpawnOptions, options);
|
||
|
callback = callback || function(){};
|
||
|
}
|
||
|
|
||
|
var
|
||
|
child,
|
||
|
stdout = "", stderr = "",
|
||
|
shell = getShell();
|
||
|
|
||
|
try {
|
||
|
child = cp.spawn(shell.cmd, [shell.arg, command], options);
|
||
|
} catch (e) {
|
||
|
callback(e, stdout, stderr);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (child.stdout) {
|
||
|
child.stdout.on("data", function(data){
|
||
|
stdout += data;
|
||
|
});
|
||
|
}
|
||
|
|
||
|
if (child.stderr) {
|
||
|
child.stderr.on("data", function(data){
|
||
|
stderr += data;
|
||
|
});
|
||
|
}
|
||
|
|
||
|
child.on("close", function(code){
|
||
|
if (code) {
|
||
|
var e = new Error("Shell command exit with non zero code: " + code);
|
||
|
e.code = code;
|
||
|
callback(e, stdout, stderr);
|
||
|
} else {
|
||
|
callback(null, stdout, stderr);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
return child;
|
||
|
}
|
||
|
|
||
|
module.exports = execSh;
|
||
|
|