2014-12-13 3 views
11

मुझे node.js. के अंदर कुछ इंटरैक्टिव शेल कमांड चलाने होंगे चलो हमारे इंटरेक्टिव खोल $ python हो:node.js के अंदर इंटरैक्टिव शेल कमांड कैसे चलाएं?

var cp = require('child_process'); 
var pythonChildProcess = cp.spawn('python'); 

pythonChildProcess.stdout.on("data", function(data) { 
    console.log('data successfully written!', data); // never outputs anything 
}); 

pythonChildProcess.stdin.write('1 + 1'); 
pythonChildProcess.stdin.end(); 

इस कोड को उत्पादन के लिए कुछ भी नहीं है (लेकिन stdout 2 होना चाहिए)।

लेकिन अगर ऐसा होगा, तो एक और समस्या होगी: इसे कैसे इंटरैक्टिव बनाने के लिए? जब मैं pythonChildProcess.stdin.end(); पर कॉल करता हूं तो प्रक्रिया समाप्त होती है! लेकिन मैं सिर्फ stdin खत्म करना चाहता था और अगले stdin लिखना चाहता था!

यूपीडी: यदि मैं enter बटन दबाकर अनुकरण कर सकता हूं - मैं प्रक्रिया को अंतःक्रियात्मक रूप से लिखने में सक्षम हूं। लेकिन इनपुट स्ट्रिंग के अंत में \n जोड़ना मदद नहीं करता है।

+0

"अंत stdin के लिए और अगले stdin लिखने"? क्या आप समझा सकते हैं कि इसका क्या मतलब है? –

+0

@ E_net4, मैं '$ python' कमांड निष्पादित करना चाहता हूं, कुछ इनपुट लिखें (उदाहरण के लिए '1 + 1')," दबाएं' एंटर करें ", कुछ आउटपुट प्राप्त करें (मामले में' 2'), फिर लिखें एक और इनपुट ('10 + 10')," प्रेस 'एंटर करें "फिर से, कुछ और आउटपुट प्राप्त करें, फिर कुछ और इनपुट लिखें और इसी तरह ... और" इनपुट "के ऐसे अनुक्रम जिन्हें मैंने" stdins "नाम दिया है –

+0

वे वास्तव में हैं एक एकल स्टडीन स्ट्रीम, जिसमें आप इनपुट की कई पंक्तियां भेजना चाहते हैं। –

उत्तर

4

सबसे पहले और सबसे महत्वपूर्ण बात यह है कि अन्य इंटरैक्टिव गोले के साथ इंटरफेसिंग से नोड को रोकने वाली चीजों में से एक यह है कि बच्चे के आवेदन को "इंटरैक्टिव" व्यवहार रखना चाहिए, भले ही stdin टर्मिनल जैसा न लगे। python यहां पता था कि इसका stdin टर्मिनल नहीं था, इसलिए उसने काम करने से इनकार कर दिया। इसे -i ध्वज को पायथन कमांड में जोड़कर ओवरराइड किया जा सकता है।

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

इंटरैक्टिव शैल में एकाधिक इनपुट भेजने के लिए आप ऐसा कुछ कर सकते हैं, जबकि अभी भी प्रत्येक परिणाम एक-एक करके पुनर्प्राप्त करने में सक्षम है। यह कोड लंबे आउटपुट के लिए प्रतिरोधी होगा, जब तक कि एक और निर्देश करने से पहले एक पूर्ण लाइन प्राप्त नहीं हो जाती तब तक उन्हें जमा करना। कई निर्देश एक समय में भी किए जा सकते हैं, जो कि बेहतर हो सकता है अगर वे अभिभावक प्रक्रिया 'राज्य पर निर्भर न हों। अपने लक्ष्य को पूरा करने के लिए अन्य असीमित संरचनाओं के साथ प्रयोग करने के लिए स्वतंत्र महसूस करें।

var cp = require('child_process'); 
var childProcess = cp.spawn('python', ['-i']); 

childProcess.stdout.setEncoding('utf8') 

var k = 0; 
var data_line = ''; 

childProcess.stdout.on("data", function(data) { 
    data_line += data; 
    if (data_line[data_line.length-1] == '\n') { 
    // we've got new data (assuming each individual output ends with '\n') 
    var res = parseFloat(data_line); 
    data_line = ''; // reset the line of data 

    console.log('Result #', k, ': ', res); 

    k++; 
    // do something else now 
    if (k < 5) { 
     // double the previous result 
     childProcess.stdin.write('2 * + ' + res + '\n'); 
    } else { 
     // that's enough 
     childProcess.stdin.end(); 
    } 
    } 
}); 


childProcess.stdin.write('1 + 0\n'); 
3

@ ई_नेट 4 के उत्तर का एक टीएल संस्करण, जो कोड को पढ़कर समझते हैं। एक विस्तृत स्पष्टीकरण के लिए, कृपया उसका उत्तर पढ़ें। उन्होंने इसे अच्छी तरह से वर्णित किया है।

var spawn = require('child_process').spawn 

var p = spawn('node',['-i']); 

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

p.stdin.write('1 + 0\n'); 

आउटपुट:

> 
1 
संबंधित मुद्दे