Execute a command line binary with Node.js

后端 未结 12 2221
星月不相逢
星月不相逢 2020-11-22 01:39

I am in the process of porting a CLI library from Ruby over to Node.js. In my code I execute several third party binaries when necessary. I am not sure how best to accomplis

12条回答
  •  灰色年华
    2020-11-22 01:54

    I just wrote a Cli helper to deal with Unix/windows easily.

    Javascript:

    define(["require", "exports"], function (require, exports) {
        /**
         * Helper to use the Command Line Interface (CLI) easily with both Windows and Unix environments.
         * Requires underscore or lodash as global through "_".
         */
        var Cli = (function () {
            function Cli() {}
                /**
                 * Execute a CLI command.
                 * Manage Windows and Unix environment and try to execute the command on both env if fails.
                 * Order: Windows -> Unix.
                 *
                 * @param command                   Command to execute. ('grunt')
                 * @param args                      Args of the command. ('watch')
                 * @param callback                  Success.
                 * @param callbackErrorWindows      Failure on Windows env.
                 * @param callbackErrorUnix         Failure on Unix env.
                 */
            Cli.execute = function (command, args, callback, callbackErrorWindows, callbackErrorUnix) {
                if (typeof args === "undefined") {
                    args = [];
                }
                Cli.windows(command, args, callback, function () {
                    callbackErrorWindows();
    
                    try {
                        Cli.unix(command, args, callback, callbackErrorUnix);
                    } catch (e) {
                        console.log('------------- Failed to perform the command: "' + command + '" on all environments. -------------');
                    }
                });
            };
    
            /**
             * Execute a command on Windows environment.
             *
             * @param command       Command to execute. ('grunt')
             * @param args          Args of the command. ('watch')
             * @param callback      Success callback.
             * @param callbackError Failure callback.
             */
            Cli.windows = function (command, args, callback, callbackError) {
                if (typeof args === "undefined") {
                    args = [];
                }
                try {
                    Cli._execute(process.env.comspec, _.union(['/c', command], args));
                    callback(command, args, 'Windows');
                } catch (e) {
                    callbackError(command, args, 'Windows');
                }
            };
    
            /**
             * Execute a command on Unix environment.
             *
             * @param command       Command to execute. ('grunt')
             * @param args          Args of the command. ('watch')
             * @param callback      Success callback.
             * @param callbackError Failure callback.
             */
            Cli.unix = function (command, args, callback, callbackError) {
                if (typeof args === "undefined") {
                    args = [];
                }
                try {
                    Cli._execute(command, args);
                    callback(command, args, 'Unix');
                } catch (e) {
                    callbackError(command, args, 'Unix');
                }
            };
    
            /**
             * Execute a command no matters what's the environment.
             *
             * @param command   Command to execute. ('grunt')
             * @param args      Args of the command. ('watch')
             * @private
             */
            Cli._execute = function (command, args) {
                var spawn = require('child_process').spawn;
                var childProcess = spawn(command, args);
    
                childProcess.stdout.on("data", function (data) {
                    console.log(data.toString());
                });
    
                childProcess.stderr.on("data", function (data) {
                    console.error(data.toString());
                });
            };
            return Cli;
        })();
        exports.Cli = Cli;
    });
    

    Typescript original source file:

     /**
     * Helper to use the Command Line Interface (CLI) easily with both Windows and Unix environments.
     * Requires underscore or lodash as global through "_".
     */
    export class Cli {
    
        /**
         * Execute a CLI command.
         * Manage Windows and Unix environment and try to execute the command on both env if fails.
         * Order: Windows -> Unix.
         *
         * @param command                   Command to execute. ('grunt')
         * @param args                      Args of the command. ('watch')
         * @param callback                  Success.
         * @param callbackErrorWindows      Failure on Windows env.
         * @param callbackErrorUnix         Failure on Unix env.
         */
        public static execute(command: string, args: string[] = [], callback ? : any, callbackErrorWindows ? : any, callbackErrorUnix ? : any) {
            Cli.windows(command, args, callback, function () {
                callbackErrorWindows();
    
                try {
                    Cli.unix(command, args, callback, callbackErrorUnix);
                } catch (e) {
                    console.log('------------- Failed to perform the command: "' + command + '" on all environments. -------------');
                }
            });
        }
    
        /**
         * Execute a command on Windows environment.
         *
         * @param command       Command to execute. ('grunt')
         * @param args          Args of the command. ('watch')
         * @param callback      Success callback.
         * @param callbackError Failure callback.
         */
        public static windows(command: string, args: string[] = [], callback ? : any, callbackError ? : any) {
            try {
                Cli._execute(process.env.comspec, _.union(['/c', command], args));
                callback(command, args, 'Windows');
            } catch (e) {
                callbackError(command, args, 'Windows');
            }
        }
    
        /**
         * Execute a command on Unix environment.
         *
         * @param command       Command to execute. ('grunt')
         * @param args          Args of the command. ('watch')
         * @param callback      Success callback.
         * @param callbackError Failure callback.
         */
        public static unix(command: string, args: string[] = [], callback ? : any, callbackError ? : any) {
            try {
                Cli._execute(command, args);
                callback(command, args, 'Unix');
            } catch (e) {
                callbackError(command, args, 'Unix');
            }
        }
    
        /**
         * Execute a command no matters what's the environment.
         *
         * @param command   Command to execute. ('grunt')
         * @param args      Args of the command. ('watch')
         * @private
         */
        private static _execute(command, args) {
            var spawn = require('child_process').spawn;
            var childProcess = spawn(command, args);
    
            childProcess.stdout.on("data", function (data) {
                console.log(data.toString());
            });
    
            childProcess.stderr.on("data", function (data) {
                console.error(data.toString());
            });
        }
    }
    
    Example of use:
    
        Cli.execute(Grunt._command, args, function (command, args, env) {
            console.log('Grunt has been automatically executed. (' + env + ')');
    
        }, function (command, args, env) {
            console.error('------------- Windows "' + command + '" command failed, trying Unix... ---------------');
    
        }, function (command, args, env) {
            console.error('------------- Unix "' + command + '" command failed too. ---------------');
        });
    

提交回复
热议问题