Рубрики
Без рубрики

Выполнение команд Shell с Node.js

С узлом мы можем запустить команды оболочки и обрабатывать их ввод / вывод, используя JavaScript, вместо языка сценариев оболочки. Это облегчает приложение для обслуживания и развития, когда мы остаемся в той же среде.

Автор оригинала: Arpan Abhishek.

Вступление

Системные администраторы и разработчики часто обращаются к автоматизации, чтобы уменьшить свою рабочую нагрузку и улучшить свои процессы. При работе с серверами автоматизированные задачи часто сценариются сценариями Shell. Тем не менее, разработчик может предпочесть использовать более общий язык более высокого уровня для сложных задач. Многие приложения также должны взаимодействовать с файловой системой и другими компонентами ОС, которые часто более легко делаются с утилитами уровня командной строки.

С Node.js мы можем запустить команды оболочки и обрабатывать их входы и выходы, используя JavaScript. Следовательно, мы можем написать большую часть этих сложных операций в JavaScript вместо языка сценариев оболочки, потенциально сделав программу проще для обслуживания.

В этой статье мы узнаем различные способы выполнения команд Shell в Node.js, используя Child_Process модуль.

Модуль Child_Proccess

Node.js выполняет свой основной контур событий в одном потоке. Однако это не значит, что вся его обработка выполняется в этом одном потоке. Асинхронные задачи в Node.js выполняются в других внутренних потоках. Когда они завершены, код в обратном вызове или ошибках возвращается в основной, один поток.

Эти различные потоки выполняются в том же процессе Node.js. Однако иногда желательно создать еще один процесс для выполнения кода. Когда создается новый процесс, операционная система определяет, какой процессор он использует и как планировать свои задачи.

Child_Process Модуль создает новые детские процессы нашего основного процесса Node.js. Мы можем выполнить команды оболочки с этими дочерними процессами.

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

Однако мы можем делегировать этот ресурсный интенсивный код дочерним процессом, скажем, очень эффективная программа C ++. Затем наш код Node.js затем выполнит, что программа C ++ в новом процессе, не блокируя свои другие действия, а при полной обработке его вывода.

Две функции, которые мы будем использовать для выполнения команд оболочки exec и Спон Отказ

Функция exec.

EXEC () Функция создает новую оболочку и выполняет заданную команду. Выход из выполнения буферизован, что означает хранить в памяти и доступен для использования в обратном вызове.

Давайте использовать EXEC () Функция для перечисления всех папок и файлов в нашем текущем каталоге. В новом файле Node.js называется lsexec.js Напишите следующий код:

const { exec } = require("child_process");

exec("ls -la", (error, stdout, stderr) => {
    if (error) {
        console.log(`error: ${error.message}`);
        return;
    }
    if (stderr) {
        console.log(`stderr: ${stderr}`);
        return;
    }
    console.log(`stdout: ${stdout}`);
});

Во-первых, нам требуется Child_Process Модуль в нашей программе, специально используя EXEC () Функция (через разрушимость ES6). Далее мы называем EXEC () Функция с двумя параметрами:

  • Строка с командой оболочки мы хотим выполнить.
  • Функция обратного вызова с тремя параметрами: Ошибка . , stdout , Стдерр Отказ

Команда оболочки, которую мы бегаем, это ls -la , который должен перечислять все файлы и папки в нашей текущей строке каталога по строке, включая скрытые файлы/папки. Функция обратного вызова журнал, есть ли мы Ошибка . Попытка выполнить команду или выводить на оболочке stdout или Стдерр потоки.

Примечание: Ошибка . Объект отличается от Стдерр Отказ Ошибка . Объект не нулевой, когда Child_Process Модуль не выполняет команду. Это может произойти, если вы попытаетесь выполнить другой сценарий Node.js в EXEC () Но файл не может быть найден, например. С другой стороны, если команда успешно работает и записывает сообщение стандартному потоку ошибок, то Стдерр Объект не будет нулевым.

Если вы запустите этот файл Node.js, вы должны увидеть вывод, аналогичный:

$ node lsExec.js
stdout: total 0
[email protected] 9 arpan arpan  0 Dec  7 00:14 .
[email protected] 4 arpan arpan  0 Dec  7 22:09 ..
[email protected] 1 arpan arpan  0 Dec  7 15:10 lsExec.js

child process exited with code 0

Теперь, когда мы поняли, как запустить команды с EXEC () Давайте узнаем другой способ выполнить команды с Spawn () Отказ

Функция порождения

Spawn () Функция выполняет команду в A Новый процесс Отказ Эта функция использует Поток API Таким образом, его выход команды сделан доступным через слушателей.

Аналогично раньше, мы будем использовать Spawn () Функция для перечисления всех папок и файлов в нашем текущем каталоге. Давайте создадим новый файл Node.js, lsspawn.js и введите следующее:

const { spawn } = require("child_process");

const ls = spawn("ls", ["-la"]);

ls.stdout.on("data", data => {
    console.log(`stdout: ${data}`);
});

ls.stderr.on("data", data => {
    console.log(`stderr: ${data}`);
});

ls.on('error', (error) => {
    console.log(`error: ${error.message}`);
});

ls.on("close", code => {
    console.log(`child process exited with code ${code}`);
});

Мы начинаем, требуя от Spawn () Функция из Child_Process модуль. Затем мы создаем новый процесс, который выполняет Ls команда, прохождение -la как аргумент. Обратите внимание, как аргументы проводятся в массиве и не включены в командную строку.

Затем мы создадим наших слушателей. stdout объект Ls , пожали данные событие, когда команда записывает этот поток. Точно так же Стдерр также пожаровал данные событие, когда команда записывает этот поток.

Ошибки пойманы, прослушивая их непосредственно на объекте, который хранит ссылку на команду. Вы получите ошибку, только если Child_Process не выполняет команду.

Закрыть событие возникает, когда команда закончилась.

Если мы запустим этот файл Node.js, мы должны получить вывод, как раньше с EXEC () :

$ node lsSpawn.js
stdout: total 0
[email protected] 9 arpan arpan  0 Dec  7 00:14 .
[email protected] 4 arpan arpan  0 Dec  7 22:09 ..
[email protected] 1 arpan arpan  0 Dec  7 15:10 lsExec.js
[email protected] 1 arpan arpan  0 Dec  7 15:40 lsSpawn.js

child process exited with code 0

Когда использовать Exec и Spawn?

Ключевая разница между EXEC () и Spawn () как они возвращают данные. Как EXEC () Магазин все вывод в буфере, это больше памяти интенсивно, чем Spawn () , который потирает вывод так, как приходит.

Как правило, если вы не ожидаете возвращения большого количества данных, вы можете использовать EXEC () для простоты. Хорошие примеры использования случаев использования создают папку или получают статус файла. Однако, если вы ожидаете большой объем вывода из вашей команды, то вам следует использовать Spawn () Отказ Хорошим примером будет использоваться команда для управления двоичными данными, а затем загрузка его в программу Node.js.

Заключение

Node.js может запустить команды оболочки, используя стандарт Child_Process модуль. Если мы используем EXEC () Функция, наша команда будет работать, и его вывод будет доступен для нас в обратном вызове. Если мы используем Spawn () Модуль, его выход будет доступен по слушателям событий.

Если наше приложение ожидает много вывода из наших команд, мы должны предпочтить Spawn () над EXEC () Отказ Если нет, мы могли бы выбрать использовать EXEC () для его простоты.

Теперь, когда вы можете запустить задачи внешние на Node.js, какие приложения вы бы построили?