nodejs
Node.js에서 외부 명령어를 실행하고 그 결과를 한 번에 받아오고 싶을 때 사용하는 대표적인 함수가 바로
이 글에서는
const { exec } = require('child_process');
exec('ls -l', (error, stdout, stderr) => {
if (error) {
console.error(`에러 발생: ${error.message}`);
return;
}
if (stderr) {
console.error(`stderr: ${stderr}`);
return;
}
console.log(`stdout: ${stdout}`);
});
첫 번째 인자는 실행할 전체 쉘 명령어 문자열입니다. 예를 들어 'ls -l' 또는 'cat file.txt | grep hello' 같은 형태로 사용할 수 있습니다.
두 번째 인자인 콜백 함수는 총 세 개의 인자를 받습니다. 첫 번째 인자인 error는 명령 실행 도중 오류가 발생했을 때의 에러 객체를 나타냅니다. 두 번째 인자인 stdout는 명령어 실행 결과로 표준 출력된 내용을 문자열로 담고 있으며, 세 번째 인자인 stderr는 에러 출력 스트림에 출력된 내용을 담고 있습니다. 따라서 실행 결과를 처리할 때는 이 세 가지를 모두 분기하여 활용하는 것이 좋습니다.
exec는 외부 명령어의 실행 결과를 한 번에 문자열 형태로 받아올 수 있는 간단한 실행 방식입니다. 실행된 명령의 표준 출력(stdout)과 표준 에러(stderr)를 버퍼에 저장한 뒤, 실행이 완료된 후 콜백으로 전달합니다. 따라서 전체 결과가 적은 작업에 적합하며, 간단한 CLI 명령 실행에 자주 사용됩니다.
반면 spawn은 스트리밍 방식으로 출력을 처리할 수 있기 때문에 출력이 많거나 실행 시간이 긴 작업에 더 적합합니다. exec는 내부적으로 쉘을 사용하기 때문에 명령어 문자열 내에서 파이프(|)나 리디렉션(>) 같은 쉘 문법도 그대로 사용할 수 있습니다.
가장 기본적인 활용 예입니다.
const { exec } = require('child_process');
exec('ls', (error, stdout, stderr) => {
if (error) {
console.error(`명령 실행 중 에러 발생: ${error.message}`);
return;
}
if (stderr) {
console.error(`에러 스트림: ${stderr}`);
return;
}
console.log(`디렉토리 목록 출력 결과:
${stdout}`);
});
이번에는
exec('cat file.txt | grep hello', (error, stdout, stderr) => {
if (error) {
console.error(`실행 오류: ${error.message}`);
return;
}
if (stderr) {
console.error(`에러 내용: ${stderr}`);
return;
}
console.log(`'hello'가 포함된 줄:
${stdout}`);
});
exec('echo $HAN_PY', {
env: { ...process.env, HAN_PY: '테스트' },
cwd: process.cwd(), // 현재 작업 디렉토리
timeout: 5000 // 실행 시간 제한 (ms)
}, (error, stdout, stderr) => {
if (error) {
console.error(`명령 실패: ${error.message}`);
return;
}
if (stderr) {
console.error(`에러 출력: ${stderr}`);
return;
}
console.log(`HAN_PY 값: ${stdout.trim()}`);
});
이처럼
exec('some-heavy-cmd', { maxBuffer: 1024 * 1024 }, (err, stdout) => {
console.log(stdout);
});
복잡한 명령어를 파이프라인으로 연결하거나, 쉘 명령어를 그대로 실행할 수 있다는 점도 큰 장점입니다. 단, 출력 결과가 많을 수 있다면