Что такое child_process в Node.js и какие методы он предоставляет?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое child_process в Node.js и какие методы он предоставляет?
child_process — встроенный модуль для создания и управления дочерними процессами. Это необходимо для выполнения системных команд, запуска скриптов и распределения вычислений между процессами.
1. exec() — выполнение команд в shell
Запускает команду в shell и буферизирует весь вывод:
const { exec } = require('child_process');
// Простой вызов
exec('ls -la', (error, stdout, stderr) => {
if (error) {
console.error(`Error: ${error.message}`);
return;
}
console.log(`Output: ${stdout}`);
});
// С опциями
exec('npm list', {
cwd: '/home/user/projects',
timeout: 5000,
maxBuffer: 1024 * 1024
}, (error, stdout, stderr) => {
console.log(stdout);
});
Плюсы: Простой синтаксис, поддержка shell операций Минусы: Весь вывод в памяти, уязвимо для injection
2. execFile() — выполнение файлов напрямую
Запускает файл без shell, безопаснее:
const { execFile } = require('child_process');
// Безопаснее чем exec
execFile('ls', ['-la', '/tmp'], (error, stdout, stderr) => {
if (error) throw error;
console.log(stdout);
});
// Node.js скрипт
execFile('node', ['script.js', 'arg1', 'arg2'], (error, stdout, stderr) => {
console.log(stdout);
});
// Безопасно для пользовательского ввода
const fileName = userInput;
execFile('cat', [fileName], (error, stdout, stderr) => {
console.log(stdout);
}); // Нет injection атак
Плюсы: Безопаснее, быстрее, аргументы передаются массивом Минусы: Нет shell функций
3. spawn() — потоковый процесс
Запускает процесс с потоковым выводом (память эффективно):
const { spawn } = require('child_process');
// Потоковый вывод
const ls = spawn('ls', ['-la', '/tmp']);
ls.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
ls.stderr.on('data', (data) => {
console.error(`stderr: ${data}`);
});
ls.on('close', (code) => {
console.log(`Process exited with code ${code}`);
});
Потоковое общение:
const child = spawn('cat');
child.stdin.write('Hello\n');
child.stdin.write('World\n');
child.stdin.end();
child.stdout.on('data', (data) => {
console.log(`output: ${data}`);
});
Плюсы: Потоковая обработка, хороша для больших данных Минусы: Более сложный синтаксис
4. fork() — Node.js процессы с IPC
Создаёт дочерний Node.js процесс с IPC каналом:
// parent.js
const { fork } = require('child_process');
const child = fork('child.js');
// Отправить сообщение
child.send({ hello: 'world' });
// Получить сообщение
child.on('message', (msg) => {
console.log('Message from child:', msg);
});
child.on('exit', (code, signal) => {
console.log('Child exited with code', code);
});
child.js:
process.on('message', (msg) => {
console.log('Message from parent:', msg);
process.send({ result: 'processed' });
});
Плюсы: IPC, идеален для распределения вычислений Минусы: Только для Node.js
Практические примеры
Worker pool:
const { fork } = require('child_process');
const workers = [];
for (let i = 0; i < 4; i++) {
workers.push(fork('worker.js'));
}
workers[0].send({ task: 'compute', data: [1, 2, 3] });
workers[0].on('message', (result) => {
console.log('Result:', result);
});
Потоковая обработка файлов:
const { spawn } = require('child_process');
const cat = spawn('cat', ['huge-file.log']);
cat.stdout.on('data', (chunk) => {
console.log(`Processing ${chunk.length} bytes`);
});
Timeout для процесса:
const { execFile } = require('child_process');
const child = execFile('sleep', ['10'], callback);
setTimeout(() => {
child.kill('SIGTERM');
}, 5000);
Сравнение методов
| Метод | Использование | Плюсы | Минусы |
|---|---|---|---|
| exec() | Простые команды | Shell поддержка | Injection уязвимость |
| execFile() | Файлы с аргументами | Безопаснее | Нет shell |
| spawn() | Большие данные | Потоки | Сложнее |
| fork() | Node.js процессы | IPC | Только Node.js |
Обработка ошибок
const { exec } = require('child_process');
exec('unknown-command', (error, stdout, stderr) => {
if (error) {
console.error(`Error code: ${error.code}`);
console.error(`Error signal: ${error.signal}`);
console.error(`stderr: ${stderr}`);
return;
}
console.log(stdout);
});
Лучшие практики
// ✅ Правильно — execFile с аргументами
execFile('curl', ['https://example.com'], callback);
// ❌ Неправильно — уязвимо для injection
const url = userInput;
exec(`curl ${url}`, callback);
// ✅ Правильно — spawn для больших данных
const child = spawn('large-process');
child.stdout.on('data', callback);
// ✅ Правильно — явно убить процесс
const child = spawn('command');
setTimeout(() => child.kill(), 5000);
Итог
- exec() — простые shell команды
- execFile() — файлы с аргументами, безопаснее
- spawn() — потоковые данные, длительные процессы
- fork() — Node.js процессы с IPC для параллелизма