[node.js] node.js에서 쉘 명령의 출력을 실행하고 가져옵니다.

node.js에서 Unix 터미널 명령의 출력을 얻는 방법을 찾고 싶습니다. 이렇게 할 수있는 방법이 있습니까?

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



답변

그것이 제가 지금 작업하고있는 프로젝트에서하는 방식입니다.

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


답변

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

Renato가 지적한 바와 같이, 지금도 몇 가지 동기식 exec 패키지 가 있습니다. 찾고있는 것보다 더 많은 sync-exec 를 참조하십시오 . 하지만 node.js는 단일 스레드 고성능 네트워크 서버로 설계되었으므로 이것이 사용하려는 경우 시작하는 동안에 만 사용하지 않는 한 sync-exec 종류의 항목을 피하십시오. 또는 뭔가.


답변

7.6 이후의 노드를 사용하고 콜백 스타일이 마음에 들지 않으면 node-util의 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 / catch비동기 코드 내에서 처리 할 수 ​​있습니다 .


답변

Renato 답변 덕분에 정말 기본적인 예를 만들었습니다.

const exec = require('child_process').exec

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

전역 git 사용자 이름을 인쇄합니다. 🙂


답변

요구 사항

이를 위해서는 Promises 및 Async / Await를 지원하는 Node.js 7 이상이 필요합니다.

해결책

promise를 활용하여 child_process.exec명령 의 동작을 제어하는 ​​래퍼 함수를 ​​만듭니다 .

설명

promise와 비동기 함수를 사용하면 콜백 지옥에 빠지지 않고 매우 깔끔한 API를 사용하여 출력을 반환하는 셸의 동작을 모방 할 수 있습니다. 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

온라인으로 시도하십시오.

Repl.it .

외부 자원

약속 .

child_process.exec.

Node.js 지원 테이블 .


답변