Node.js child_process 모듈 — 자식 프로세스 실행
Node.js child_process 모듈 — 자식 프로세스 실행
Node.js 프로그램 안에서 외부 명령을 실행하거나 별도의 프로세스를 띄워야 할 때가 있어요. 예를 들어 셸 명령을 실행한다든지, 다른 Node.js 스크립트를 별도 프로세스로 돌린다든지요. node:child_process 모듈은 그런 자식 프로세스 생성 기능을 제공해요.
node:child_process 모듈은 popen(3)과 비슷하지만 완전히 같지는 않은 방식으로 서브프로세스를 생성해요. 이 기능은 주로 child_process.spawn()으로 제공돼요.
const { spawn } = require('node:child_process');
const ls = spawn('ls', ['-lh', '/usr']);
ls.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
ls.stderr.on('data', (data) => {
console.error(`stderr: ${data}`);
});
ls.on('close', (code) => {
console.log(`child process exited with code ${code}`);
});
기본적으로 부모 Node.js 프로세스와 생성된 서브프로세스 사이에 stdin·stdout·stderr용 파이프가 만들어져요. 이 파이프들은 제한된(플랫폼마다 다른) 용량을 가져요. 서브프로세스가 이 한도를 넘는 stdout을 쓰면서 출력을 소비하지 않으면, 파이프 버퍼가 더 받아들일 때까지 서브프로세스가 블록돼요. 셸의 파이프와 똑같은 동작이에요. 출력을 소비하지 않는다면 { stdio: 'ignore' } 옵션을 쓰면 돼요.
명령 탐색은 env 옵션이 주어지면 그 options.env.PATH, 아니면 부모 프로세스의 환경 변수 PATH를 사용해요.
비동기 프로세스 생성
서브프로세스를 비동기로 생성하는 함수는 여러 가지가 있어요.
const { exec, execFile, fork, spawn } = require('node:child_process');
child_process.exec(command[, options][, callback])— 셸에서 명령을 실행하고 결과를 수집child_process.execFile(file[, args][, options][, callback])— 파일(실행 파일)을 직접 실행child_process.fork(modulePath[, args][, options])— Node.js 모듈을 별도 프로세스로 실행 (IPC 통신 포함)child_process.spawn(command[, args][, options])— 명령을 인자와 함께 실행하고 스트림으로 입출력 처리
동기 프로세스 생성
동기 버전도 있어요. execFileSync, execSync, spawnSync가 그것이에요. 외부 명령의 결과를 기다렸다가 값을 받아야 하는 단순한 상황에서 편리해요.
const { execSync } = require('node:child_process');
const output = execSync('echo hello');
ChildProcess 클래스
spawn() 등이 반환하는 ChildProcess 객체는 'close', 'error', 'exit', 'message', 'spawn' 같은 이벤트를 내보내고, subprocess.stdout, subprocess.stderr 같은 스트림과 subprocess.pid, subprocess.exitCode 같은 프로퍼티를 가져요. subprocess.kill([signal])로 신호를 보내 프로세스를 종료할 수도 있어요.
정리하면, child_process 모듈은 외부 명령 실행과 별도 프로세스 관리를 위한 스폰·실행·포크·동기 API를 제공하고, ChildProcess 객체로 입출력 스트림과 이벤트를 제어할 수 있게 해 줘요.