← Назад к вопросам

Что такое child_process в Node.js и какие методы он предоставляет?

2.2 Middle🔥 141 комментариев
#API и сетевые протоколы#Node.js и JavaScript

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое 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 для параллелизма