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


113

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"
}

이것은 중복입니까, 아니면 완전히 다른 것을 설명합니까? stackoverflow.com/questions/7183307/…
Anderson Green

이것은 당신이 관심을 가질 수 있습니다.
benekastah

답변:


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
이 함수가 명령의 출력을 반환하도록 할 수 있습니까? (그게 제가하려고했던 것입니다.)
Anderson Green

1
그게 코드가하는 일입니다. 난 그냥 만든 편집의 예를 살펴 걸릴
레나토 가마를

2
@AndersonGreen 셸 명령을 비동기 적으로 실행하기 때문에 "return"키보드로 함수가 정상적으로 반환되는 것을 원하지 않을 것입니다. 결과적으로 셸 명령이 완료 될 때 실행해야하는 코드와 함께 콜백을 전달하는 것이 좋습니다.
Nick McCurdy

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

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


1
이 경우 명령의 출력을 어떻게 얻을 수 있습니까? 명령 줄 출력을 포함하는 "stdout"입니까?
Anderson Green

또한 콜백을 사용하지 않고 비슷한 일을 할 수 있습니까?
Anderson Green

맞습니다. stdout은 프로그램의 출력을 포함합니다. 그리고 아니요, 콜백 없이는 불가능합니다. node.js의 모든 것은 non-blocking을 지향합니다. 즉, IO를 할 때마다 콜백을 사용하게됩니다.
hexist

자바 스크립트를 사용하여 출력을 기다리고 싶은 스크립트 작업을 수행하려는 경우 v8 쉘, d8
hexist

@hexist 일부가 Sync그것을 피해야한다하더라도 이럴 있도록 방법을 기본적으로 사용할 수
레나토 가마

29

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비동기 코드 내에서 처리 할 수 ​​있습니다 .


이거 해봤 어? 나는 { stdout: string, stderr: string }결과를 얻고 있다await exec(...)
fwoelffel

1
예, 이것이 stdout과 stderr을 포함 하여 전체 셸 출력을 제공한다는 것을 분명히해야했습니다 . 출력 만 원하는 경우 마지막 줄을 다음으로 변경할 수 있습니다 return { name: name.stdout.trim(), email: email.stdout.trim() }..
Ansikt

16

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

const exec = require('child_process').exec

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

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


11

요구 사항

이를 위해서는 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 지원 테이블 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.