UNPKG

nyx_server

Version:

Node内容发布

115 lines (97 loc) 3.65 kB
/* global process */ var cp = require('child_process'); var path = require('path'); var Promise = require('bluebird'); var _ = require('lodash'); var which = require('which'); var log4js = require("log4js"); var log = log4js.getLogger("cmd"); //var PThrottler = require('p-throttler'); 暂时先不使用 var createError = require('./createError'); // The concurrency limit here is kind of magic. You don't really gain a lot from // having a large number of commands spawned at once, so it isn't super // important for this number to be large. However, it would still be nice to // *know* how high this number can be, rather than having to guess low. //var throttler = new PThrottler(50); var winBatchExtensions; var winWhichCache; var isWin = process.platform === 'win32'; if (isWin) { winBatchExtensions = ['.bat', '.cmd']; winWhichCache = {}; } function getWindowsCommand(command) { var fullCommand; var extension; // Do we got the value converted in the cache? if (_.has(winWhichCache, command)) { return winWhichCache[command]; } // Use which to retrieve the full command, which puts the extension in the end try { fullCommand = which.sync(command); } catch (err) { return winWhichCache[command] = command; } extension = path.extname(fullCommand).toLowerCase(); // Does it need to be converted? if (winBatchExtensions.indexOf(extension) === -1) { return winWhichCache[command] = command; } return winWhichCache[command] = fullCommand; } // Executes a shell command, buffering the stdout and stderr // If an error occurs, a meaningful error is generated // Returns a promise that gets fulfilled if the command succeeds // or rejected if it fails function executeCmd(command, args, options) { log.debug("命令行参数 : "+JSON.stringify(arguments)) var process; var stderr = ''; var stdout = ''; return new Promise(function(resolve , reject){ // Windows workaround for .bat and .cmd files, see #626 if (isWin) { command = getWindowsCommand(command); } // Buffer output, reporting progress process = cp.spawn(command, args, options); process.stdout.on('data', function (data) { data = data.toString(); stdout += data; }); process.stderr.on('data', function (data) { data = data.toString(); stderr += data; }); // If there is an error spawning the command, reject the promise process.on('error', reject); // Listen to the close event instead of exit // They are similar but close ensures that streams are flushed process.on('close', function (code) { var fullCommand; var error; if (code) { // Generate the full command to be presented in the error message if (!Array.isArray(args)) { args = []; } fullCommand = command; fullCommand += args.length ? ' ' + args.join(' ') : ''; // Build the error instance error = createError('Failed to execute "' + fullCommand + '", exit code of #' + code, 'ECMDERR', { stdout : stdout, details: stderr, exitCode: code }); reject(error); return; } resolve([stdout, stderr]); }); }); } function cmd(command, args, options) { return executeCmd(command, args, options); } module.exports = cmd;