Node.js के साथ एक कमांड लाइन बाइनरी निष्पादित करें


647

मैं रूबी से Node.js. तक एक CLI लाइब्रेरी को पोर्ट करने की प्रक्रिया में हूं। अपने कोड में मैं आवश्यक होने पर कई तृतीय पक्ष बायनेरी निष्पादित करता हूं। मुझे यकीन नहीं है कि नोड में इसे पूरा करने के लिए कितना अच्छा है।

यहाँ एक उदाहरण है रूबी में जहाँ मैं एक फाइल को एक पीडीएफ में बदलने के लिए प्रिंसएक्सएमएल कहता हूं:

cmd = system("prince -v builds/pdf/book.html -o builds/pdf/book.pdf")

नोड में समतुल्य कोड क्या है?


3
यह लाइब्रेरी शुरू करने के लिए एक अच्छी जगह है। यह आपको सभी ओएस प्लेटफार्मों पर प्रक्रियाओं को स्पॉन करने की अनुमति देता है।
ओब्सीडियन


2
सबसे सरल है child_process.exec का उपयोग करना, यहां कुछ अच्छे उदाहरण हैं
drorw

जवाबों:


1068

Node.js (v8.1.4) के नए संस्करण के लिए, ईवेंट्स और कॉल पुराने संस्करणों के समान या समान हैं, लेकिन यह मानक नई भाषा सुविधाओं का उपयोग करने के लिए प्रोत्साहित किया जाता है। उदाहरण:

बफर के लिए, गैर-स्ट्रीम स्वरूपित आउटपुट (आप इसे एक ही बार में प्राप्त करते हैं), उपयोग करें child_process.exec:

const { exec } = require('child_process');
exec('cat *.js bad_file | wc -l', (err, stdout, stderr) => {
  if (err) {
    // node couldn't execute the command
    return;
  }

  // the *entire* stdout and stderr (buffered)
  console.log(`stdout: ${stdout}`);
  console.log(`stderr: ${stderr}`);
});

आप इसका उपयोग वादों के साथ भी कर सकते हैं:

const util = require('util');
const exec = util.promisify(require('child_process').exec);

async function ls() {
  const { stdout, stderr } = await exec('ls');
  console.log('stdout:', stdout);
  console.log('stderr:', stderr);
}
ls();

यदि आप डेटा को क्रम में धीरे-धीरे प्राप्त करना चाहते हैं (एक स्ट्रीम के रूप में आउटपुट), तो उपयोग करें child_process.spawn:

const { spawn } = require('child_process');
const child = spawn('ls', ['-lh', '/usr']);

// use child.stdout.setEncoding('utf8'); if you want text chunks
child.stdout.on('data', (chunk) => {
  // data from standard output is here as buffers
});

// since these are streams, you can pipe them elsewhere
child.stderr.pipe(dest);

child.on('close', (code) => {
  console.log(`child process exited with code ${code}`);
});

इन दोनों कार्यों में एक समकालिक समकक्ष है। इसके लिए एक उदाहरण child_process.execSync:

const { execSync } = require('child_process');
// stderr is sent to stderr of parent process
// you can set options.stdio if you want it to go elsewhere
let stdout = execSync('ls');

साथ ही child_process.spawnSync:

const { spawnSync} = require('child_process');
const child = spawnSync('ls', ['-lh', '/usr']);

console.log('error', child.error);
console.log('stdout ', child.stdout);
console.log('stderr ', child.stderr);

नोट: निम्नलिखित कोड अभी भी कार्यात्मक है, लेकिन मुख्य रूप से ES5 और उससे पहले के उपयोगकर्ताओं पर लक्षित है।

Node.js के साथ बच्चे की प्रक्रियाओं को जन्म देने के लिए मॉड्यूल प्रलेखन (v5.0.0) में अच्छी तरह से प्रलेखित है । एक कमांड निष्पादित करने और बफर के रूप में इसका पूरा आउटपुट लाने के लिए, उपयोग करें child_process.exec:

var exec = require('child_process').exec;
var cmd = 'prince -v builds/pdf/book.html -o builds/pdf/book.pdf';

exec(cmd, function(error, stdout, stderr) {
  // command output is in stdout
});

यदि आपको स्ट्रीम के साथ I / O हैंडल प्रक्रिया का उपयोग करने की आवश्यकता है, जैसे कि जब आप बड़ी मात्रा में आउटपुट की उम्मीद कर रहे हैं, तो उपयोग करें child_process.spawn:

var spawn = require('child_process').spawn;
var child = spawn('prince', [
  '-v', 'builds/pdf/book.html',
  '-o', 'builds/pdf/book.pdf'
]);

child.stdout.on('data', function(chunk) {
  // output will be here in chunks
});

// or if you want to send output elsewhere
child.stdout.pipe(dest);

यदि आप कमांड के बजाय किसी फ़ाइल को निष्पादित कर रहे हैं, तो आप उपयोग करना चाह सकते हैं child_process.execFile, कौन से पैरामीटर जो लगभग समान हैं spawn, लेकिन execआउटपुट बफ़र्स को प्राप्त करने के लिए एक चौथा कॉलबैक पैरामीटर है । यह इस तरह से लग सकता है:

var execFile = require('child_process').execFile;
execFile(file, args, options, function(error, stdout, stderr) {
  // command output is in stdout
});

V0.11.12 के अनुसार , नोड अब तुल्यकालिक spawnऔर समर्थन करता है exec। ऊपर वर्णित सभी विधियाँ अतुल्यकालिक हैं, और एक तुल्यकालिक समकक्ष है। उनके लिए प्रलेखन यहाँ पाया जा सकता है । जब वे स्क्रिप्टिंग के लिए उपयोगी होते हैं, तो ध्यान दें कि चाइल्ड प्रक्रियाओं को एसिंक्रोनस रूप से स्पॉन करने के लिए उपयोग किए जाने वाले तरीकों के विपरीत, सिंक्रोनस तरीकों की एक आवृत्ति वापस नहीं आती है ChildProcess


19
धन्यवाद। यह मुझे पागल कर रहा था। कभी-कभी यह केवल स्पष्ट समाधान को इंगित करने में मदद करता है ताकि हम नॉब्स (नोड से) सीख सकें और इसके साथ चल सकें।
डेव थॉम्पसन

10
ध्यान दें: ('child_process') की आवश्यकता है। निष्पादक () उन लोगों के लिए ब्याज की होगी, जिन्हें यहां राजकुमार जैसे सिस्टम-वाइड ज्ञात कमांड के बजाय एक फ़ाइल चलाने की आवश्यकता है।
लुइस एमलिन

2
इसके बजाय child.pipe(dest)(जो मौजूद नहीं है), आपको उपयोग करना होगा child.stdout.pipe(dest)और child.stderr.pipe(dest), जैसे child.stdout.pipe(process.stdout)और child.stderr.pipe(process.stderr)
ComFreek

क्या होगा अगर मैं सब कुछ एक फ़ाइल में नहीं डालना चाहता, लेकिन मैं एक से अधिक कमांड निष्पादित करना चाहता हूं? हो सकता है कि जैसे echo "hello"और echo "world"
कैमरून

यह ऐसा करने का मानक तरीका है? मेरा मतलब है कि सभी आवरणों को नोडज में कैसे लिखा जाता है? मेरा मतलब है कि गियरमैन, रैबिटमैक इत्यादि के लिए कहने की आवश्यकता है जो कमांड को चलाने के लिए आवश्यक है लेकिन उनके पास कुछ आवरण भी हैं लेकिन मुझे उनके लाइब्रेरी कोड में कोई भी कोड नहीं मिल सकता है
ANINJa

261

नोड जेएस v13.9.0, एलटीएस v12.16.1, और v10.19.0 --- मार्च 2020

Async विधि (यूनिक्स):

'use strict';

const { spawn } = require( 'child_process' );
const ls = spawn( 'ls', [ '-lh', '/usr' ] );

ls.stdout.on( 'data', data => {
    console.log( `stdout: ${data}` );
} );

ls.stderr.on( 'data', data => {
    console.log( `stderr: ${data}` );
} );

ls.on( 'close', code => {
    console.log( `child process exited with code ${code}` );
} );


Async विधि (Windows):

'use strict';

const { spawn } = require( 'child_process' );
const dir = spawn('cmd', ['/c', 'dir'])

dir.stdout.on( 'data', data => console.log( `stdout: ${data}` ) );
dir.stderr.on( 'data', data => console.log( `stderr: ${data}` ) );
dir.on( 'close', code => console.log( `child process exited with code ${code}` ) );


सिंक:

'use strict';

const { spawnSync } = require( 'child_process' );
const ls = spawnSync( 'ls', [ '-lh', '/usr' ] );

console.log( `stderr: ${ls.stderr.toString()}` );
console.log( `stdout: ${ls.stdout.toString()}` );

से Node.js v13.9.0 प्रलेखन

वही Node.js v12.16.1 दस्तावेज़ीकरण और Node.js v10.19.0 प्रलेखन के लिए जाता है


8
उचित और सरल दोनों संस्करण देने के लिए धन्यवाद। थोड़ा सरल सिंक संस्करण मेरे एक "कुछ करने और इसे दूर फेंक" स्क्रिप्ट के लिए पूरी तरह से ठीक था जो मुझे चाहिए था।
ब्रायन जोर्डन

कोई दिक्कत नहीं है! हमेशा दोनों को अच्छा लगता है भले ही यह कुछ के अनुसार "उचित" न हो।
iSkore

7
यह इंगित करने के लायक हो सकता है कि विंडोज में इस उदाहरण को करने के लिए, एक का उपयोग करना होगा 'cmd', ['/c', 'dir']। कम से कम मैं सिर्फ उच्च और निम्न खोज कर रहा था कि 'dir'बिना तर्क के काम क्यों नहीं होता, इससे पहले कि मुझे यह याद रहे ...?)
एंडियो

1
इन आउटपुट में से कोई भी कंसोल को कुछ भी नहीं।
टायुगी 7

@ Tyguy7 आप इसे कैसे चला रहे हैं? और क्या आपके पास कंसोल ऑब्जेक्ट पर कोई ओवरराइड है?
iSkore

73

आप child_process.exec देख रहे हैं

यहाँ उदाहरण है:

const exec = require('child_process').exec;
const child = exec('cat *.js bad_file | wc -l',
    (error, stdout, stderr) => {
        console.log(`stdout: ${stdout}`);
        console.log(`stderr: ${stderr}`);
        if (error !== null) {
            console.log(`exec error: ${error}`);
        }
});

यह सही है। लेकिन इस बात का ध्यान रखें कि इस तरह की कॉलिंग को चाइल्ड-प्रोसेस की लंबाई के लिए सीमाएं हैं।
होजेबेल

@ अहबेबल, फिर विकल्प क्या है?
हर्षदीप

2
@ हर्षदीप लंबे स्टडआउट आउटपुट (कई एमबी उदा) के मामले में आप स्टडआउट की dataघटनाओं को सुन सकते हैं । डॉक्स में देखें, लेकिन यह कुछ इस तरह होना चाहिए childProc.stdout.on("data", fn)
होजेबेल

30
const exec = require("child_process").exec
exec("ls", (error, stdout, stderr) => {
 //do whatever here
})

14
यह कोड कैसे काम करता है और यह उत्तर कैसे हल करता है, इसके लिए कृपया अधिक विवरण जोड़ें। याद रखें कि StackOverflow भविष्य में इसे पढ़ने वाले लोगों के लिए उत्तरों का एक संग्रह बना रहा है।
अल स्विगार्ट

4
अल ने जो कहा वह सच है, लेकिन मैं कहूंगा कि इस उत्तर का लाभ यह है कि यह किसी के लिए शीर्ष उत्तर के माध्यम से पढ़ने की तुलना में बहुत सरल है, जिसे त्वरित प्रतिक्रिया की आवश्यकता है।

29

संस्करण 4 के बाद से निकटतम विकल्प child_process.execSyncविधि है:

const {execSync} = require('child_process');

let output = execSync('prince -v builds/pdf/book.html -o builds/pdf/book.pdf');

ध्यान दें कि execSyncब्लॉक इवेंट लूप को कॉल करें।


यह नवीनतम नोड पर बहुत अच्छा काम करता है। हालांकि एक child_processका उपयोग करते हुए बनाया जा रहा है execSync? और क्या यह कमांड के ठीक बाद हटा दिया जाता है, है ना? तो कोई स्मृति लीक?
NiCk Newman

1
हां, मेमोरी लीक नहीं है। मुझे लगता है कि यह केवल लिब्युव चाइल्ड प्रोसेस स्ट्रक्चर्स को इनिशियलाइज़ करता है बिना इसे नोड में बनाए।
पॉल रुमकिन

21

यदि आप ऐसा कुछ चाहते हैं जो शीर्ष उत्तर से मिलता जुलता हो लेकिन समकालिक हो तो यह काम करेगा।

var execSync = require('child_process').execSync;
var cmd = "echo 'hello world'";

var options = {
  encoding: 'utf8'
};

console.log(execSync(cmd, options));

14

मैंने यूनिक्स / विंडोज़ से आसानी से निपटने के लिए सिर्फ एक क्ली हेल्पर लिखा है।

जावास्क्रिप्ट:

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;
});

टाइपस्क्रिप्ट मूल स्रोत फ़ाइल:

 /**
 * 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. ---------------');
    });

1
सीएलआई में ग्रंट
Vadorequest

7

अब आप शेलज (नोड v4 से) का उपयोग इस प्रकार कर सकते हैं:

var shell = require('shelljs');

shell.echo('hello world');
shell.exec('node --version')

6

यदि आप निर्भरता को बुरा नहीं मानते हैं और वादों, child-process-promiseकार्यों का उपयोग करना चाहते हैं :

स्थापना

npm install child-process-promise --save

निष्पादन

var exec = require('child-process-promise').exec;

exec('echo hello')
    .then(function (result) {
        var stdout = result.stdout;
        var stderr = result.stderr;
        console.log('stdout: ', stdout);
        console.log('stderr: ', stderr);
    })
    .catch(function (err) {
        console.error('ERROR: ', err);
    });

स्पॉन का उपयोग

var spawn = require('child-process-promise').spawn;

var promise = spawn('echo', ['hello']);

var childProcess = promise.childProcess;

console.log('[spawn] childProcess.pid: ', childProcess.pid);
childProcess.stdout.on('data', function (data) {
    console.log('[spawn] stdout: ', data.toString());
});
childProcess.stderr.on('data', function (data) {
    console.log('[spawn] stderr: ', data.toString());
});

promise.then(function () {
        console.log('[spawn] done!');
    })
    .catch(function (err) {
        console.error('[spawn] ERROR: ', err);
    });

4

इस हल्के npmपैकेज का उपयोग करें :system-commands

इसे यहां देखें

इसे इस तरह आयात करें:

const system = require('system-commands')

इस तरह से कमांड चलाएं:

system('ls').then(output => {
    console.log(output)
}).catch(error => {
    console.error(error)
})

उत्तम! मेरी जरूरतों के लिए महान काम करता है।
रूजवेल्ट

3

@ हेक्सासैनाइड का उत्तर लगभग पूर्ण है। पर विंडोज आदेश princeहो सकता है prince.exe, prince.cmd, prince.batया बस prince(मैं कैसे जवाहरात इकट्ठा किए गए की कोई बारे में पता कर रहा हूँ, लेकिन NPM डिब्बे एक श स्क्रिप्ट और एक बैच स्क्रिप्ट के साथ आते हैं - npmऔर npm.cmd)। यदि आप एक पोर्टेबल स्क्रिप्ट लिखना चाहते हैं जो यूनिक्स और विंडोज पर चलेगी, तो आपको सही निष्पादन योग्य स्पॉन करना होगा।

यहाँ एक सरल अभी तक पोर्टेबल स्पॉन फ़ंक्शन है:

function spawn(cmd, args, opt) {
    var isWindows = /win/.test(process.platform);

    if ( isWindows ) {
        if ( !args ) args = [];
        args.unshift(cmd);
        args.unshift('/c');
        cmd = process.env.comspec;
    }

    return child_process.spawn(cmd, args, opt);
}

var cmd = spawn("prince", ["-v", "builds/pdf/book.html", "-o", "builds/pdf/book.pdf"])

// Use these props to get execution results:
// cmd.stdin;
// cmd.stdout;
// cmd.stderr;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.