नोड.जेएस में शेल कमांड का उत्पादन और निष्पादित करें


113

एक नोड.जेएस में, मैं एक यूनिक्स टर्मिनल कमांड के आउटपुट को प्राप्त करने का एक तरीका खोजना चाहता हूं। क्या इसे करने का कोई तरीका है?

function getCommandOutput(commandString){
    // now how can I implement this function?
    // getCommandOutput("ls") should print the terminal output of the shell command "ls"
}

क्या यह एक डुप्लिकेट है, या यह कुछ पूरी तरह से अलग वर्णन करता है? stackoverflow.com/questions/7183307/…
एंडरसन ग्रीन

यह आपकी रुचि हो सकती है।
बेनेकास्तह

जवाबों:


142

जिस तरह से मैं इसे एक परियोजना में कर रहा हूं, अब मैं काम कर रहा हूं।

var exec = require('child_process').exec;
function execute(command, callback){
    exec(command, function(error, stdout, stderr){ callback(stdout); });
};

उदाहरण: रिटिटिंग git उपयोगकर्ता

module.exports.getGitUser = function(callback){
    execute("git config --global user.name", function(name){
        execute("git config --global user.email", function(email){
            callback({ name: name.replace("\n", ""), email: email.replace("\n", "") });
        });
    });
};

3
क्या इस फ़ंक्शन को कमांड का आउटपुट वापस करना संभव है? (यही मैं करने की कोशिश कर रहा था।)
एंडरसन ग्रीन

1
कि कोड क्या करता है। मेरे द्वारा अभी संपादित किए गए संपादन पर एक नज़र डालें
गामा

2
@AndersonGreen आप फ़ंक्शन को "वापसी" कीबोर्ड के साथ सामान्य रूप से नहीं लौटना चाहेंगे, क्योंकि यह शेल कमांड को अतुल्यकालिक रूप से चला रहा है। नतीजतन, कोड के साथ कॉलबैक में पास करना बेहतर है जो शेल कमांड पूरा होने पर चलना चाहिए।
निक मैक्कर्डी

1
आउच, आपका पहला नमूना उस कॉलबैक को कॉल करते समय त्रुटि की संभावना को अनदेखा करता है। मुझे आश्चर्य है कि stdoutअगर कोई त्रुटि होती है तो क्या होता है । उम्मीद है कि निर्धारक और प्रलेखित।
doug65536

31

आप child_process की तलाश कर रहे हैं

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

child = exec(command,
   function (error, stdout, stderr) {
      console.log('stdout: ' + stdout);
      console.log('stderr: ' + stderr);
      if (error !== null) {
          console.log('exec error: ' + error);
      }
   });

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


1
इस मामले में, मैं कमांड का आउटपुट कैसे प्राप्त कर सकता हूं? क्या "stdout" में कमांड-लाइन आउटपुट है?
एंडरसन ग्रीन

इसके अलावा, क्या कॉलबैक का उपयोग किए बिना कुछ समान करना संभव है?
एंडरसन ग्रीन

सही, stdout में प्रोग्राम का आउटपुट होता है। और नहीं, यह कॉलबैक के बिना करना संभव नहीं है। नोड.जेएस में सब कुछ गैर-अवरुद्ध होने के आसपास उन्मुख है, जिसका अर्थ है कि हर बार जब आप आईओ करते हैं तो आप कॉलबैक का उपयोग करने जा रहे हैं।
हेक्सिस्ट

ध्यान दें कि यदि आप स्क्रिप्ट का उपयोग करने के लिए जावास्क्रिप्ट का उपयोग करने की तलाश कर रहे हैं, तो ऐसी चीजें जहां आप वास्तव में आउटपुट पर इंतजार करना चाहते हैं और उस तरह की चीज, आप v8 शेल, d8
हेक्सिस्ट

@ नक्सलवादी कुछ Syncतरीके हैं जो मूल रूप से उपलब्ध हैं, यहां तक ​​कि IMHO से भी बचा जाना चाहिए
रेनाटो गामा

29

यदि आप बाद में 7.6 से अधिक नोड का उपयोग कर रहे हैं और आपको कॉलबैक शैली पसंद नहीं है, तो आप शेल कमांड प्राप्त करने के लिए नोड-यूज़ के promisifyफ़ंक्शन का भी उपयोग कर सकते हैं async / awaitजो सफाई से पढ़ते हैं। इस तकनीक का उपयोग करते हुए, स्वीकृत उत्तर का एक उदाहरण दिया गया है:

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

module.exports.getGitUser = async function getGitUser () {
  const name = await exec('git config --global user.name')
  const email = await exec('git config --global user.email')
  return { name, email }
};

इसमें विफल आदेशों पर अस्वीकार किए गए वादे को वापस करने का अतिरिक्त लाभ भी है, जिसे try / catchasync कोड के साथ संभाला जा सकता है ।


क्या आपने यह कोशिश की है? मैं { stdout: string, stderr: string }एक परिणाम के रूप में मिल रहा हूँawait exec(...)
fwoelffel

1
हाँ, मुझे स्पष्ट करना चाहिए कि यह आपको पूर्ण शेल आउटपुट देता है, जिसमें स्टडआउट और स्टडर दोनों शामिल हैं। तुम सिर्फ उत्पादन चाहते हैं, आप के लिए अंतिम पंक्ति को बदल सकता है: return { name: name.stdout.trim(), email: email.stdout.trim() }
Ansikt

16

रेनाटो जवाब के लिए धन्यवाद, मैंने एक बहुत ही मूल उदाहरण बनाया है:

const exec = require('child_process').exec

exec('git config --global user.name', (err, stdout, stderr) => console.log(stdout))

यह सिर्फ आपके वैश्विक git यूजरनेम को प्रिंट करेगा :)


11

आवश्यकताएँ

इसके लिए Node.js 7 या बाद में Promises और Async / Await के समर्थन की आवश्यकता होगी।

उपाय

एक आवरण फ़ंक्शन बनाएं जो child_process.execकमांड के व्यवहार को नियंत्रित करने का वादा करता है ।

व्याख्या

वादों और एक अतुल्यकालिक फ़ंक्शन का उपयोग करके, आप कॉलबैक नरक में और एक सुंदर स्वच्छ एपीआई के साथ गिरने के बिना, आउटपुट को वापस करने वाले शेल के व्यवहार की नकल कर सकते हैं। awaitकीवर्ड का उपयोग करके , आप एक स्क्रिप्ट बना सकते हैं जो आसानी से पढ़ती है, जबकि अभी भी काम child_process.execपूरा करने में सक्षम है।

कोड नमूना

const childProcess = require("child_process");

/**
 * @param {string} command A shell command to execute
 * @return {Promise<string>} A promise that resolve to the output of the shell command, or an error
 * @example const output = await execute("ls -alh");
 */
function execute(command) {
  /**
   * @param {Function} resolve A function that resolves the promise
   * @param {Function} reject A function that fails the promise
   * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
   */
  return new Promise(function(resolve, reject) {
    /**
     * @param {Error} error An error triggered during the execution of the childProcess.exec command
     * @param {string|Buffer} standardOutput The result of the shell command execution
     * @param {string|Buffer} standardError The error resulting of the shell command execution
     * @see https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback
     */
    childProcess.exec(command, function(error, standardOutput, standardError) {
      if (error) {
        reject();

        return;
      }

      if (standardError) {
        reject(standardError);

        return;
      }

      resolve(standardOutput);
    });
  });
}

प्रयोग

async function main() {
  try {
    const passwdContent = await execute("cat /etc/passwd");

    console.log(passwdContent);
  } catch (error) {
    console.error(error.toString());
  }

  try {
    const shadowContent = await execute("cat /etc/shadow");

    console.log(shadowContent);
  } catch (error) {
    console.error(error.toString());
  }
}

main();

नमूना आउटपुट

root:x:0:0::/root:/bin/bash
[output trimmed, bottom line it succeeded]

Error: Command failed: cat /etc/shadow
cat: /etc/shadow: Permission denied

इसे ऑनलाइन आज़माएं।

रिप्लाई करें

बाहरी संसाधन

वादा करता है

child_process.exec

Node.js समर्थन तालिका

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.