प्रदर्शन: प्रदर्शन "लाइव"


187

मेरे पास यह सरल स्क्रिप्ट है:

var exec = require('child_process').exec;

exec('coffee -cw my_file.coffee', function(error, stdout, stderr) {
    console.log(stdout);
});

जहाँ मैं बस कॉफी-स्क्रिप्ट फ़ाइल संकलित करने के लिए एक कमांड निष्पादित करता हूं। लेकिन स्टडआउट कंसोल में कभी प्रदर्शित नहीं होते हैं, क्योंकि कमांड कभी समाप्त नहीं होती है (कॉफी के -w विकल्प के कारण)। यदि मैं कमांड को कंसोल से सीधे निष्पादित करता हूं तो मुझे इस तरह का संदेश मिलता है:

18:05:59 - compiled my_file.coffee

मेरा प्रश्न यह है कि क्या नोड संदेश के साथ इन संदेशों को प्रदर्शित करना संभव है। यदि हाँ तो कैसे? !

धन्यवाद


1
मैं यहाँ पायथन निष्पादन योग्य से stdout कैप्चरिंग की तलाश में आया था। ध्यान दें कि नीचे दिए गए सभी काम करेंगे, लेकिन आपको "-यू" विकल्प के साथ अजगर को चलाने की जरूरत है, ताकि आउटबाउंड अनबाउंड किया जा सके और जिससे लाइव अपडेट हो।
एंडी

जवाबों:


264

उपयोग न करें execspawnजो एक EventEmmiterवस्तु है उसका उपयोग करें । तब आप सुन सकते हैं stdout/ stderrघटनाओं ( spawn.stdout.on('data',callback..)) के रूप में वे होते हैं

NodeJS प्रलेखन से:

var spawn = require('child_process').spawn,
    ls    = spawn('ls', ['-lh', '/usr']);

ls.stdout.on('data', function (data) {
  console.log('stdout: ' + data.toString());
});

ls.stderr.on('data', function (data) {
  console.log('stderr: ' + data.toString());
});

ls.on('exit', function (code) {
  console.log('child process exited with code ' + code.toString());
});

exec आउटपुट को बफ़र करता है और आमतौर पर इसे तब वापस करता है जब कमांड ने निष्पादन समाप्त कर दिया है।


22
बहुत अच्छा। FYI करें: stdout / stderr ईवेंट कॉलबैक तर्क 'डेटा' एक बफ़र है इसलिए इसे .toString () के साथ कॉल करें
सर्जेल

4
आप में से जो लोग विंडोज पर काम करने के लिए स्पॉन नहीं ला सकते हैं, वे इस बेहतरीन जवाब पर एक नजर डालें ।
टोमेक्वी

17
निष्पादन भी कम से कम नवीनतम में एक EventEmitter है।
निकोले त्सेन्कोव

4
यह भी ध्यान रखें कि जब भी प्रोग्राम एक नई रूपरेखा तैयार करता है, तो कॉलबैक नहीं कहा जाएगा। यदि आप चाइल्ड प्रोसेस से "इवेंट्स" प्राप्त करना चाहते हैं, तो इस प्रक्रिया को flush(stdout);Node.js. में ईवेंट को फायर करने के लिए बफर ( C) में फ्लश करना चाहिए।
जुलियन एफ। वेनर्ट

5
+1 भी एक EventEmitter होने के नाते .. एक आर्गन सरणी (बहुत लंबी और जटिल ffmpeg कमांड लाइन) में मेरी स्ट्रिंग को फिर से भरने पर 2 घंटे बिताए .. केवल यह पता लगाने के लिए कि मुझे वास्तव में ज़रूरत नहीं थी।
deadconversations

176

exec एक ChildProcess ऑब्जेक्ट जो एक EventEmitter है, भी लौटाएगा।

var exec = require('child_process').exec;
var coffeeProcess = exec('coffee -cw my_file.coffee');

coffeeProcess.stdout.on('data', function(data) {
    console.log(data); 
});

या pipeबच्चे की प्रक्रिया मुख्य स्टडआउट के लिए है।

coffeeProcess.stdout.pipe(process.stdout);

या स्पॉन का उपयोग करके वंशानुगत stdio

spawn('coffee -cw my_file.coffee', { stdio: 'inherit' });

35
ऐसा लगता है कि बस का उपयोग करके इसे सरल किया जा सकता है pipe:coffeeProcess.stdout.pipe(process.stdout);
एरिक फ्रीज

3
@ एरिकफ्रेज की टिप्पणी वह है जो मैं ढूंढ रहा था, क्योंकि मैं stdout के पात्रों के प्रतिस्थापन की सुविधा (एक नोड स्क्रिप्ट में
प्रोट्रेक्टर का

19
सरल: spawn(cmd, argv, { stdio: 'inherit' })। अलग-अलग उदाहरणों के लिए नोडज्स . org/api/child_process.html#child_process_options_stdio देखें ।
मॉर्गन टोवरे क्विंग

3
@ MorganTouvereyQuilling के सुझाव का उपयोग करने के लिए +1 spawnके साथ stdio: 'inherit'। यह execपाइपिंग stdout/ और से अधिक सटीक आउटपुट का उत्पादन करता है stderr, उदाहरण के लिए जब ए से प्रगति की जानकारी प्रदर्शित होती है git clone
लिवइन

56

पहले से ही कई उत्तर हैं लेकिन उनमें से कोई भी ऐसा करने के लिए सबसे अच्छा (और सबसे आसान) तरीके का उल्लेख नहीं करता है, जो कि उपयोग spawnऔर { stdio: 'inherit' }विकल्प है । यह सबसे सटीक आउटपुट का उत्पादन करता प्रतीत होता है, उदाहरण के लिए जब ए से प्रगति की जानकारी प्रदर्शित होती है git clone

बस यह करें:

var spawn = require('child_process').spawn;

spawn('coffee', ['-cw', 'my_file.coffee'], { stdio: 'inherit' });

इस टिप्पणी में इस ओर इशारा करने के लिए @MorganTouvereyQuilling को श्रेय ।


1
मैंने पाया कि जब उपप्रकार रंगीन पाठ की तरह स्वरूपित आउटपुट का उपयोग करता है, तो stdio: "inherit"उस स्वरूपण को संरक्षित child.stdout.pipe(process.stdout)करता है जबकि ऐसा नहीं करता है।
रिक्की गिब्सन

यह पूरी तरह से npm स्थापित पर प्रगति सलाखों की तरह जटिल उत्पादन के साथ प्रक्रियाओं पर भी उत्पादन को संरक्षित करता है। बहुत बढ़िया!
डेव कू

1
यह स्वीकृत उत्तर क्यों नहीं है? यह केवल एक ही था जो मेरे लिए काम करता था और यह सिर्फ 2 f * लाइनें है !!!
लिंकन

प्रगति की सलाखों का उपयोग करने वाले कुछ सिम्फनी कमांड-लाइन अनुप्रयोगों को निष्पादित करते समय यह टिप सहायक था। चीयर्स।
हॉफस्टॉप

यह स्वीकृत उत्तर होना चाहिए-केवल एक चीज जो सही आउटपुट प्रतिनिधित्व को संरक्षित करती है और यह सबसे सरल है? हाँ कृपया
evnp

21

मैं बस यह जोड़ना चाहूंगा कि बफर स्पिंग्स को आउटपुट के साथ एक छोटी सी समस्या के साथ एक स्पैन्ड प्रोसेस से console.log()जोड़ा जाता है, जिससे इसमें न्यूलाइन्स जुड़ते हैं, जो अतिरिक्त लाइनों पर आपके स्पैन्ड प्रोसेस आउटपुट को फैला सकता है। आप उत्पादन तो stdoutया stderrसाथ process.stdout.write()के बजाय console.log(), तो आप पैदा की प्रक्रिया 'जैसी है' से सांत्वना उत्पादन मिलेगा।

मैंने उस समाधान को यहां देखा: Node.js: एक अनुगामी न्यूलाइन के बिना कंसोल पर मुद्रण?

आशा है कि ऊपर दिए गए समाधान का उपयोग करने में किसी को मदद मिलती है (जो लाइव आउटपुट के लिए एक बढ़िया है, भले ही यह प्रलेखन से हो)।


1
यहाँ तक spawn(command, args, { stdio: 'inherit' })कि @MorganTouvereyQuilling द्वारा सुझाए गए और भी अधिक सटीक आउटपुट उपयोग के लिए , यहां stackoverflow.com/questions/10232192/…
Livven

20

नथानेल स्मिथ के जवाब और एरिक फ्रेज़ की टिप्पणी से प्रेरित होकर, यह उतना ही सरल हो सकता है:

var exec = require('child_process').exec;
exec('coffee -cw my_file.coffee').stdout.pipe(process.stdout);

यह साधारण कमांड के लिए ठीक काम करता है, lsलेकिन अधिक जटिल कमांड जैसे कि के लिए विफल रहता है npm install। मैंने भी स्टडआउट और स्टेडर दोनों को उनके संबंधित प्रक्रिया ऑब्जेक्ट्स को पाइप करने की कोशिश की।
linuxdan

@linuxdan यह हो सकता है क्योंकि npm stderr में लिख रहा है (मैंने देखा कि कुछ वहाँ प्रगति पट्टी लिखते हैं)। आप stderr को पाइप भी कर सकते हैं, या stderr पर सुनने के लिए Tongfa समाधान का विस्तार कर सकते हैं।
सेरगुई

@linuxdan मैंने जो सबसे विश्वसनीय तरीका देखा है spawn(command, args, { stdio: 'inherit' }), जैसा कि यहां बताया गया है stackoverflow.com/questions/10232192/…
Livven

12

मैंने अपनी उपयोगिताओं में एक कस्टम निष्पादन स्क्रिप्ट जोड़ने में मददगार पाया है जो ऐसा करते हैं।

utilities.js

const { exec } = require('child_process')

module.exports.exec = (command) => {
  const process = exec(command)

  process.stdout.on('data', (data) => {
    console.log('stdout: ' + data.toString())
  })

  process.stderr.on('data', (data) => {
    console.log('stderr: ' + data.toString())
  })

  process.on('exit', (code) => {
    console.log('child process exited with code ' + code.toString())
  })
}

app.js

const { exec } = require('./utilities.js')

exec('coffee -cw my_file.coffee')

5

अन्य सभी उत्तरों की समीक्षा करने के बाद, मैंने इसे समाप्त किया:

function oldSchoolMakeBuild(cb) {
    var makeProcess = exec('make -C ./oldSchoolMakeBuild',
         function (error, stdout, stderr) {
             stderr && console.error(stderr);
             cb(error);
        });
    makeProcess.stdout.on('data', function(data) {
        process.stdout.write('oldSchoolMakeBuild: '+ data);
    });
}

कभी-कभी dataकई लाइनें होंगी, इसलिए oldSchoolMakeBuildहेडर एक बार कई लाइनों के लिए दिखाई देगा। लेकिन इसने मुझे इसे बदलने के लिए पर्याप्त परेशान नहीं किया।


3

child_process.spawn किसी वस्तु को stdout और stderr धाराओं के साथ लौटाता है। आप डेटा को पढ़ने के लिए स्टडआउट स्ट्रीम पर टैप कर सकते हैं कि बच्चे की प्रक्रिया नोड को वापस भेजती है। stdout में एक स्ट्रीम "डेटा", "एंड" और अन्य इवेंट्स होते हैं जो स्ट्रीम होते हैं। स्पॉन का सबसे अच्छा उपयोग तब किया जाता है जब आप चाहते हैं कि बच्चे की प्रक्रिया में बड़ी मात्रा में डेटा नोड में वापस आ जाए - छवि प्रसंस्करण, द्विआधारी डेटा पढ़ना आदि।

इसलिए आप नीचे दिए गए अनुसार child_process.spawn का उपयोग करके अपनी समस्या को हल कर सकते हैं।

var spawn = require('child_process').spawn,
ls = spawn('coffee -cw my_file.coffee');

ls.stdout.on('data', function (data) {
  console.log('stdout: ' + data.toString());
});

ls.stderr.on('data', function (data) {
  console.log('stderr: ' + data.toString());
});

ls.on('exit', function (code) {
  console.log('code ' + code.toString());
});

1

यहाँ टाइप टाइप में लिखा गया एक async हेल्पर फंक्शन है जो मेरे लिए ट्रिक का काम करता है। मुझे लगता है कि यह लंबे समय तक रहने वाली प्रक्रियाओं के लिए काम नहीं करेगा लेकिन फिर भी किसी के लिए काम कर सकता है?

import * as child_process from "child_process";

private async spawn(command: string, args: string[]): Promise<{code: number | null, result: string}> {
    return new Promise((resolve, reject) => {
        const spawn = child_process.spawn(command, args)
        let result: string
        spawn.stdout.on('data', (data: any) => {
            if (result) {
                reject(Error('Helper function does not work for long lived proccess'))
            }
            result = data.toString()
        })
        spawn.stderr.on('data', (error: any) => {
            reject(Error(error.toString()))
        })
        spawn.on('exit', code => {
            resolve({code, result})
        })
    })
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.