Вызов и исполнение бинарных команд из Node.js

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Чтобы запустить исполняемый файл из командной строки в Node.js, вам понадобится модуль child_process. Если речь идёт о задачах, ресурсоёмкость которых высока, spawn станет наилучшим выбором. В тех случаях, когда результат должен быть доступен непосредственно, используйте exec:

JS
Скопировать код
const { exec } = require('child_process');

exec('имя-вашего-исполняемого-файла', (ошибка, stdout, stderr) => {
  if (ошибка) throw ошибка; // В случае возникновения ошибки, будем генерировать исключение.
  console.log(stdout); // Выводим результат.
});

Просто замените 'имя-вашего-исполняемого-файла' на имя файла, который вы собираетесь запустить.

Кинга Идем в IT: пошаговый план для смены профессии

Принципы выбора метода запуска

Асинхронное выполнение с использованием Promises

С целью упрощения обработки ошибок и управления множеством асинхронных операций, функции с callback в Node.js можно превратить в promises с помощью util.promisify.

JS
Скопировать код
const util = require('util');
const exec = util.promisify(require('child_process').exec);

async function runBinary() {
  try {
    const { stdout, stderr } = await exec('имя-вашего-исполняемого-файла');
    console.log(stdout);
    console.error(stderr);
  } catch (ошибка) {
    console.error(`Ошибка выполнения: ${ошибка}`);
  }
}
runBinary();

Непосредственный запуск файлов с помощью execFile

Запуск исполняемых файлов при помощи execFile происходит непосредственно, что более безопасно, т.к. не создается дополнительно оболочка shell.

JS
Скопировать код
const { execFile } = require('child_process');

execFile('путь/к/вашему-исполняемому-файлу', ['аргумент1', 'аргумент2'], (ошибка, stdout, stderr) => {
  if (ошибка) throw ошибка; // В случае возникновения ошибки, генерируем исключение.
  console.log(stdout);
});

Задайте и замените 'путь/к/вашему-исполняемому-файлу' на реальный путь и определите аргументы командной строки в виде массива.

Управление потоками данных и ошибками

Получение потока данных с помощью spawn

Для работы с процессами, которые выдают большой или непрерывный поток данных, используйте child_process.spawn. Он предоставляет потоки данных для считывания и записи данных.

JS
Скопировать код
const { spawn } = require('child_process');
const child = spawn('ресурсоемкий-процесс');

child.stdout.on('data', (данные) => {
  console.log(`Полученные данные: ${данные}`);
});

child.stderr.on('data', (данные) => {
  console.error(`Ошибка: ${данные}`);
});

child.on('exit', (кодВыхода) => {
  console.log(`Процесс завершен с кодом ${кодВыхода}`);
});

Синхронное выполнение и его последствия

При использовании execSync и spawnSync результат получается непосредственно, но это может негативно сказаться на цикле обработки событий в Node.js.

JS
Скопировать код
const { execSync } = require('child_process');

let результат = execSync('имя-вашего-исполняемого-файла');
console.log(результат.toString()); // Работает синхронно и может заблокировать цикл обработки событий в Node.js!

Применяйте синхронные методы с умом, поскольку они могут снижать отзывчивость вашего приложения.

Забота о совместимости

Совместимость операционной среды

В различных операционных системах исполняемые файлы командной строки могут вести себя по-разному. Проведите детальное тестирование, чтобы избежать неожиданностей.

Корректность синтаксиса команд

Команды для исполняемых файлов должны быть корректно оформлены для оболочки, с которой вы работаете. Учитывайте контекст.

Визуализация

Node.js может рассматриваться как дирижёр оркестра двоичных файлов:

Markdown
Скопировать код
Дирижер на платформе Node.js (🎼):
  | Команды к исполняемым файлам |
       /          \
    🎻    🎺    🎷    🥁    🎹
  (/binary1) (/binary2) ...

В данной аналогии каждый "инструмент" представляет собой исполняемый файл, которым управляет Node.js:

JS
Скопировать код
const { exec } = require('child_process');
exec('/binary1', (ошибка, stdout, stderr) => {
  if (ошибка) {
    console.error(`Ошибка: ${ошибка}`);
    return;
  }
  console.log(`stdout: ${stdout}`);
  console.error(`stderr: ${stderr}`);
});

Каждый бинарный файл вносит свою ноту в общую симфонию результатов.

Работа с потоками и циклами

Обновление языковых возможностей

Node.js постоянно развивается, важно отслеживать изменения, чтобы быть в курсе обновлений модуля child_process и других ключевых API.

Надёжные источники для работы

Для глубокого понимания всех методов модуля child_process обращайтесь к официальной документации Node.js.

Особое внимание к деталям

Сложные сценарии

Модуль child_process предоставляет разнообразные настройки для управления сложными задачами, связанными с запуском процессов.

Обработка ошибок и кодов завершения

Следите за ошибками и кодами завершения процессов, чтобы корректно реагировать на возникающие проблемы.

Полезные материалы

  1. Дочерние процессы в Node.js: Всё, что вам нужно знать.
  2. Дочерний процесс | Документация Node.js v21.6.1.
  3. Выполнение команд оболочки с Node.js.
  4. Понимание execFile, spawn, exec и fork в Node.js – DZone.
  5. Необработанные отказы выполнения обещаний в Node.js | www.thecodebarbarian.com.
Свежие материалы