LHJ

I'm a FE developer.

20.8 자식 프로세스

04 Jun 2020 » js_lj

20.8 자식 프로세스

child_process 모듈은 애플리케이션에서 다른 프로그램을 실행할 때 사용합니다.
실행할 프로그램은 다른 노드 프로그램, 실행 파일, 다른 언어로 만든 스크립트여도 상관없습니다.
자식 프로세스에 대해 자세히 다루는 것은 이 책의 범위를 벗어나지만, 간단한 예제를 통해 요점만 알아보겠습니다.

child_process 모듈에서 제공하는 주요 함수는 exec, execFile, fork 입니다.
fs와 마찬가지로 이들 함수에는 동기적 버전 execSync, execFileSync, forkSync가 있습니다.
execexecFile은 운영체제에서 지원하는 실행 파일은 무엇이든 실행할 수 있습니다.
exec는 운영체제의 명령줄이나 다름없는 을 호출합니다.
따라서 명령줄에서 실행할 수 있는 것은 무엇이든 exec를 통해 실행할 수 있습니다.
execFile은 셸을 통하지 않고 실행 파일을 직접 실행하므로 메모리와 자원관리 면에서 좀 더 효율적이지만, 그만큼 더 주의해야 할 점이 있습니다.
마지막으로 fork는 다른 노드 스크립트를 실행할 때 사용합니다(물론 exec로도 실행할 수 있습니다).

NOTE_
fork는 별도의 노드 엔진을 호출하므로 소모하는 자원 면에서는 exec와 마찬가지입니다.
하지만 fork를 사용하면 프로세스 사이에 통신이 가능해집니다.
자세한 내용은 공식 문서(http://bit.ly/1PxcnL9)를 보십시오.

exec가 가장 범용적이고 덜 민감하므로 이 장에서는 exec를 사용하겠습니다.

예제에서는 디렉터리 내용을 출력하는 dir 명령어를 사용하겠습니다.
유닉스 사용자라면 ls에 더 익숙하겠지만, 대부분의 유닉스 시스템에서 ls의 별칭으로 dir을 쓸 수 있습니다.

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

exec('dir', function(err, stdout, stderr) {
    if (err) return console.error('Error executing "dir"');
    stdout = stdout.toString(); // Buffer를 문자열로 바꿉니다.
    console.log(stdout);
    stderr = stderr.toString();
    if (stderr !== '') {
        console.error('error:');
        console.error(stderr);
    }
})

exec는 셸을 호출하므로 dir 실행 파일이 존재하는 경로를 따로 지정할 필요는 없습니다.
일반적으로 시스템 셸에서 바로 실행할 수 없고 전체 경로를 써야 하는 외부 프로그램을 실행한다면 exec에서도 전체 경로를 지정해야 합니다.

호출되는 콜백은 Buffer 객체 두 개를 받습니다.
하나는 일반적인 프로그램 출력 결과인 stdout이고 다른 하나는 에러 출력 결과인 stderr입니다(에러가 있다면요).
이 예제에서는 stderr에서 출력하는 결과가 없어야 정상이므로 결과를 출력하기 전에 먼저 에러가 있는지 체크합니다.

exec는 옵션 매개변수로 options 객체를 받을 수 있습니다.
이 객체를 통해 작업 디렉터리, 환경 변수 등의 정보를 넘길 수 있습니다.
더 자세한 내용은 공식문서(https://nodejs.org/api/child_process.html)를 보십시오.

(위와 같이 작성해서 node test2 입력했더니 phpstorm에서 test.js 파일이 열리네…)

NOTE_
exec를 임포트한 부분을 보십시오.
const child_process = require(‘child_process’)로 child_process를 임포트한 다음 **child_process.exec의 별칭으로 exec를 지정하지 않고 exec를 바로 별칭으로 지정했습니다.
어느 방법이든 써도 되지만, 이 예제에서 사용한 방법이 훨씬 자주 쓰입니다.