102 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			102 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 
								 | 
							
								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
							 |