exec-sh.js 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. var cp = require('child_process')
  2. var defSpawnOptions = { stdio: 'inherit' }
  3. /**
  4. * @summary Get shell program meta for current platform
  5. * @private
  6. * @returns {Object}
  7. */
  8. function getShell () {
  9. if (process.platform === 'win32') {
  10. return { cmd: 'cmd', arg: '/C' }
  11. } else {
  12. return { cmd: 'sh', arg: '-c' }
  13. }
  14. }
  15. /**
  16. * Callback is called with the output when the process terminates. Output is
  17. * available when true is passed as options argument or stdio: null set
  18. * within given options.
  19. *
  20. * @summary Execute shell command forwarding all stdio
  21. * @param {String|Array} command
  22. * @param {Object|TRUE} [options] spawn() options or TRUE to set stdio: null
  23. * @param {Function} [callback]
  24. * @returns {ChildProcess}
  25. */
  26. function execSh (command, options, callback) {
  27. if (Array.isArray(command)) {
  28. command = command.join(';')
  29. }
  30. if (options === true) {
  31. options = { stdio: null }
  32. }
  33. if (typeof options === 'function') {
  34. callback = options
  35. options = defSpawnOptions
  36. } else {
  37. options = options || {}
  38. options = Object.assign({}, defSpawnOptions, options)
  39. callback = callback || function () {}
  40. }
  41. var child
  42. var stdout = ''
  43. var stderr = ''
  44. var shell = getShell()
  45. try {
  46. child = cp.spawn(shell.cmd, [shell.arg, command], options)
  47. } catch (e) {
  48. callback(e, stdout, stderr)
  49. return
  50. }
  51. if (child.stdout) {
  52. child.stdout.on('data', function (data) {
  53. stdout += data
  54. })
  55. }
  56. if (child.stderr) {
  57. child.stderr.on('data', function (data) {
  58. stderr += data
  59. })
  60. }
  61. child.on('close', function (code) {
  62. if (code) {
  63. var e = new Error('Shell command exit with non zero code: ' + code)
  64. e.code = code
  65. callback(e, stdout, stderr)
  66. } else {
  67. callback(null, stdout, stderr)
  68. }
  69. })
  70. return child
  71. }
  72. execSh.promise = function (command, options) {
  73. return new Promise(function (resolve, reject) {
  74. execSh(command, options, function (err, stdout, stderr) {
  75. if (err) {
  76. err.stdout = stdout
  77. err.stderr = stderr
  78. return reject(err)
  79. }
  80. resolve({
  81. stderr: stderr,
  82. stdout: stdout
  83. })
  84. })
  85. })
  86. }
  87. module.exports = execSh