SHIN
Node.js 실전 팁 20선
20편Node.js에서 쉘 명령, 다른 언어 스크립트, 또는 Node.js 모듈을 별도 프로세스로 실행할 수 있습니다.
| 메서드 | 특징 | 용도 |
|---|---|---|
| exec | 쉘 사용, 결과 버퍼링 | 간단한 명령, 소량 출력 |
| execFile | 쉘 없이 실행, 결과 버퍼링 | 실행 파일 직접 실행 |
| spawn | 스트림 방식, 실시간 출력 | 대량 출력, 장시간 프로세스 |
| fork | Node.js 전용, IPC 채널 | Node.js 모듈 분리 실행 |
const { exec } = require('child_process');
const { promisify } = require('util');
const execAsync = promisify(exec);
async function getGitLog() {
const { stdout, stderr } = await execAsync('git log --oneline -10');
if (stderr) console.error(stderr);
return stdout.trim().split('\n');
}
// 주의: 사용자 입력을 직접 삽입하면 쉘 인젝션 위험!
// ❌ exec(`ls ${userInput}`)
// ✅ execFile('ls', [userInput])const { spawn } = require('child_process');
function runPython(script, args = []) {
const py = spawn('python3', [script, ...args]);
py.stdout.on('data', (data) => {
process.stdout.write(data); // 실시간 출력
});
py.stderr.on('data', (data) => {
process.stderr.write(data);
});
return new Promise((resolve, reject) => {
py.on('close', (code) => {
code === 0 ? resolve() : reject(new Error(`종료 코드: ${code}`));
});
});
}// child.js
process.on('message', (msg) => {
const result = heavyCompute(msg.data);
process.send({ result });
});
// parent.js
const { fork } = require('child_process');
const child = fork('./child.js');
child.send({ data: 1e7 });
child.on('message', ({ result }) => {
console.log('결과:', result);
child.kill();
});const { execFile } = require('child_process');
function runWithTimeout(cmd, args, timeout = 5000) {
return new Promise((resolve, reject) => {
const proc = execFile(cmd, args, { timeout }, (err, stdout, stderr) => {
if (err?.killed) return reject(new Error('타임아웃'));
if (err) return reject(err);
resolve(stdout);
});
});
}const child = spawn('node', ['worker.js'], {
env: {
...process.env,
NODE_ENV: 'production',
SECRET_KEY: process.env.SECRET_KEY,
},
stdio: 'inherit', // 부모 프로세스의 stdio 공유
});