You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
102 lines
2.2 KiB
102 lines
2.2 KiB
4 years ago
|
var cp = require('child_process')
|
||
|
|
||
|
var 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 = Object.assign({}, defSpawnOptions, options)
|
||
|
callback = callback || function () {}
|
||
|
}
|
||
|
|
||
|
var child
|
||
|
var stdout = ''
|
||
|
var stderr = ''
|
||
|
var 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
|
||
|
}
|
||
|
|
||
|
execSh.promise = function (command, options) {
|
||
|
return new Promise(function (resolve, reject) {
|
||
|
execSh(command, options, function (err, stdout, stderr) {
|
||
|
if (err) {
|
||
|
err.stdout = stdout
|
||
|
err.stderr = stderr
|
||
|
return reject(err)
|
||
|
}
|
||
|
|
||
|
resolve({
|
||
|
stderr: stderr,
|
||
|
stdout: stdout
|
||
|
})
|
||
|
})
|
||
|
})
|
||
|
}
|
||
|
|
||
|
module.exports = execSh
|