- Выполнение Shell команд с Node.js
- Модуль child_proccess
- Функция exec
- Функция spawn
- Когда использовать exec и spawn?
- pghalliday / 1 test.js
- This comment has been minimized.
- Breme commented Feb 7, 2017
- Node.js — Масштабирование приложения с помощью child_process
- Метод exec()
- Параметры
- Пример
- Метод spawn()
- Параметры
- Пример
- Метод fork()
- Параметры
- spawn python ENOENT node.js in windows
- How should I work around this particular case?
- 2 Answers 2
Выполнение Shell команд с Node.js
Системные администраторы и разработчики часто обращаются к автоматизации, чтобы уменьшить свою рабочую нагрузку и улучшить свои процессы. При работе с серверами автоматизированные задачи часто пишутся с помощью shell сценариев. Однако разработчик может предпочесть использовать более общий язык более высокого уровня для сложных задач. Многим приложениям также необходимо взаимодействовать с файловой системой и другими компонентами уровня ОС, что часто проще сделать с помощью утилит уровня командной строки.
С Node.js мы можем запускать shell команды и обрабатывать их ввод и вывод, используя JavaScript. Поэтому мы можем написать большинство этих сложных операций на языке JavaScript вместо языка сценариев оболочки, что потенциально облегчает обслуживание программы.
В этой статье мы изучим различные способы выполнения команд оболочки в 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 и spawn , которые мы будем использовать для выполнения команд оболочки.
Функция exec
Функция exec() создает новую оболочку и выполняет заданную команду. Выходные данные выполнения буферизуются, что означает, что они хранятся в памяти и доступны для использования в обратном вызове.
Давайте использовать функцию exec() , чтобы перечислить все папки и файлы в нашем текущем каталоге. В новом файле с именем lsExec.js напишите следующий код:
Во-первых, нам нужен модуль child_process в нашей программе, в частности, с помощью функция exec() (получаем через деструктуризацию ES6). Далее мы вызываем exec() с двумя параметрами:
- Строка с командой оболочки, которую мы хотим выполнить.
- Функция обратного вызова с тремя параметрами: error , stdout , stderr .
Shell команда ls -la , которую мы запускаем, должна построчно перечислять все файлы и папки в нашем текущем каталоге, включая скрытые файлы / папки. Функция обратного вызова регистрирует, получили ли мы какое-то предупреждение в переменную error , пытаясь выполнить команду или вывод в оболочке stdout или stderr потоках.
Примечание: объект error отличается от stderr . Объект error не является нулевым, когда модуль child_process не может выполнить команду. Это может произойти, если вы попытаетесь выполнить другой Node.js скрипт, но, файл не найден. С другой стороны, если команда успешно выполняется и записывает сообщение в стандартный поток ошибок, объект stderr не будет нулевым.
Если вы запустите этот файл, вы должны увидеть вывод, подобный следующему:
Теперь, когда мы поняли, как выполнять команды exec() , давайте изучим другой способ выполнения команд с помощью функции spawn() .
Функция spawn
Функция spawn() выполняет команду в новом процессе. Эта функция использует Stream API, поэтому результат ее работы будет доступен через подписку на события.
Как и прежде, мы будем использовать эту функцию для вывода списка всех папок и файлов в нашем текущем каталоге. Давайте создадим новый Node.js файл lsSpawn.js и введем следующее:
Мы начнем с получения функции из модуля child_process . Затем мы создаем новый процесс, который выполняет команду ls -la . Обратите внимание, как аргументы shell команды хранятся в массиве.
Затем мы подписываемся на события. Объект stdout , запускает событие data , когда команда ls записывает в поток результаты своего выполнения. Аналогичным образом, stderr запускает событие data , когда shell команда возвращает ошибку в этот поток.
error выявляются при прослушивании их непосредственно на созданном объекте, в котором хранится ссылка на команду. Вы получите ошибку, только если child_process не сможете выполнить команду.
Событие close происходит, когда команда закончила свое выполнение.
Если мы запустим этот файл, мы должны получить вывод, как раньше, с exec() :
Когда использовать exec и spawn?
Основное различие между exec() и spawn() заключается в том, как они возвращают данные. Поскольку выходные данные exec() хранятся в буфере, он требует больше памяти, чем поток spawn() , который выводит данные по мере их поступления.
pghalliday / 1 test.js
var http = require ( ‘http’ ) ; |
var spawn = require ( ‘child_process’ ) . spawn ; |
var child = spawn ( |
‘CMD’ , [ |
‘/S’ , |
‘/C’ , |
‘node’ , |
‘./child.js’ |
] |
) ; |
child . stdout . pipe ( process . stdout ) ; |
child . stderr . pipe ( process . stderr ) ; |
child . on ( ‘exit’ , function ( ) < |
http . get ( ‘http://localhost:8080’ , function ( response ) < |
console . log ( ‘child did NOT die’ ) ; |
> ) . on ( ‘error’ , function ( error ) < |
console . log ( ‘child did die’ ) ; |
> ) ; |
> ) ; |
setTimeout ( function ( ) < |
http . get ( ‘http://localhost:8080’ , function ( response ) < |
response . on ( ‘end’ , function ( ) < |
console . log ( ‘kill the child’ ) ; |
child . kill ( ) ; |
> ) ; |
> ) ; |
> , 2000 ) ; |
var http = require ( ‘http’ ) ; |
var PORT = 8080 ; |
var server = http . createServer ( function ( request , response ) < |
response . end ( ) ; |
> ) ; |
server . listen ( PORT , function ( ) < |
console . log ( ‘Listening on port ‘ + PORT ) ; |
> ) ; |
V:\GitHub\node-ChildDaemon\test\Spikes\windows>node test.js |
Listening on port 8080 |
kill the child |
child did NOT die |
********* |
I can kill the process and children with ctrl-c at this point (although i expected it to kill the child and exit on it’s own) |
This comment has been minimized.
Copy link Quote reply
Breme commented Feb 7, 2017
Can you Help me on this ?
session.on(‘exec’, function (accept, reject, info) <
console.log(‘Client wants to execute: ‘ + inspect(info.command));
var stream = accept();
When I manually type the first command ‘XXXCLI ip_address’ in my command prompt and press enter,I will get a output «Connected to CLI. » .Once I get this connection successful, I need to execute my second command i.e «Lmc sample» which will load the master config and I will get the output as «Message sent..», third command will execute a script,will get output as «Message sent..» .This is what happens when I enter these commands manually in cmd prompt and execute.
What is happening is once I execute my first command i.e «XXXCLI 10.21.254.12» manually in cmd, The path where we actually execute the commands i.e( C:\users\CLI>) will not be visible. This happens because now it got connected with the above mentioned ip (10.21.254.12) .And Only after connecting to this ip ,I can able to execute my other commands.i.e command to load master config ,cmd to execute script etc.
So I want to execute my first command and get its stream in a variable and execute rest of the commands inside the stream created by first command Thanks!
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Node.js — Масштабирование приложения с помощью child_process
Дата публикации: 2017-12-27
От автора: Node.js работает в однопоточном режиме, но для обработки параллелизма использует управляемую событиями парадигму. Это также облегчает создание дочерних процессов для параллельной обработки многоядерных систем на базе процессоров.
В дочерних процессах всегда есть три потока child.stdin , child.stdout и child.stderr, которые могут совместно использоваться потоками stdio родительского процесса. Существует модуль Node js child process, который поддерживает три основных способа создания дочернего процесса.
exec — метод child_process.exec запускает команду в оболочке/консоли и буферизует вывод.
spawn — child_process.spawn запускает новый процесс с помощью заданной команды.
fork — метод child_process.fork является особым случаем spawn() для создания дочерних процессов.
Бесплатный курс «NodeJS. Быстрый старт»
Изучите курс и узнайте, как создать веб-приложение с нуля на JavaScript с NodeJS
Метод exec()
Метод child_process.exec запускает команду в оболочке и буферизирует вывод. Он содержит следующую подпись:
Параметры
Ниже приводится описание используемых параметров:
command (String) — команда для запуска с аргументами, разделенными пробелом
options (Object) — может содержать один или несколько из следующих параметров:
—cwd (String) — текущий рабочий каталог дочернего процесса
—env (Object) — ключи-значения для среды
—encoding (String) — (по умолчанию: ‘utf8′)
—shell (String) — оболочка, с которой выполняется команда (по умолчанию: ‘/ bin / sh’ в UNIX, ‘cmd.exe’ в Windows, оболочка должна понимать ключ -c в UNIX или /s/c в Windows. В Windows парсинг командной строки должен быть совместим с cmd.exe.)
—timeout (Number) — (По умолчанию: 0)
—maxBuffer (Number) — (по умолчанию: 200 * 1024)
—killSignal (String) — (по умолчанию: «SIGTERM»)
—uid (Number) — устанавливает идентификатор пользователя процесса.
—gid (Number) — устанавливает групповой идентификатор процесса.
callback — функция принимает три аргумента error , stdout и stderr, которые вызываются с выходными данными при завершении процесса.
Метод exec() возвращает буфер с максимальным размером и ожидает завершения процесса, после чего пытается сразу вернуть все буферизованные данные.
Пример
Создадим два js-файла с именем support.js и master.js —
Теперь запустите master.js:
В результате должен быть запущен сервер.
Метод spawn()
Метод child_process.spawn запускает новый процесс с помощью заданной командой. Он содержит следующую подпись:
Параметры
Ниже приводится описание используемых параметров:
command (String) — запускаемая команда
args (Array) — список аргументов строки
options (Object) — может содержать один или несколько из следующих параметров:
—cwd (String) — текущий рабочий каталог дочернего процесса.
—env (Object) — пары ключ-значение среды.
—stdio (Array) — строка конфигурации stdio дочернего процесса.
—customFds (Array) — устаревшие дескрипторы файлов для дочерних элементов, которые будут использоваться для stdio.
Бесплатный курс «NodeJS. Быстрый старт»
Изучите курс и узнайте, как создать веб-приложение с нуля на JavaScript с NodeJS
—detached (Boolean) — дочерний процесс будет лидером группы процессов.
—uid (Number) — устанавливает идентификатор пользователя процесса.
—gid (Number) — устанавливает групповой идентификатор процесса.
Метод spawn() возвращает потоки (stdout & stderr), он должен использоваться, когда процесс возвращает большой объем данных. spawn() начинает принимать ответ, сразу после начала выполнения процесса.
Пример
Создайте два js-файла с именем support.js и master.js —
Теперь запустите master.js:
Проверьте вывод. Сервер запущен
Метод fork()
Метод child_process.fork является особым случаем spawn() для создания процессов Node. Он содержит следующую подпись:
Параметры
Ниже приводится описание используемых параметров:
modulePath (String) — Модуль для запуска в дочернем элементе.
args (Array) — Список аргументов строки
options (Object) — Может содержать один или несколько из следующих параметров:
—cwd (String) — Текущий рабочий каталог дочернего процесса.
—env (Object) -Пары ключ-значение среды.
—execPath (String) — Исполняемый файл, используемый для создания дочернего процесса.
—execArgv (Array) — Список строковых аргументов, переданных исполняемому файлу (по умолчанию: process.execArgv).
—silent (Boolean) Если true, stdin, stdout и stderr для дочернего процесса будут перенаправлены в родительский процесс, иначе они будут унаследованы от родительского процесса, см. параметры «pipe» и «inherit» для stdio для spawn() (по умолчанию — false).
—uid (Number) — Устанавливает идентификатор пользователя процесса.
—gid (Number) — Устанавливает групповой идентификатор процесса.
В дополнение к тому, что он содержит все методы, что и стандартный экземпляр дочернего процесса, метод fork возвращает объект со встроенным каналом связи.
spawn python ENOENT node.js in windows
I created some code for my brother, that wanted use a python function from his node.js backend. When running it on my ubuntu computer, it works — however! When running the code on his windows machine it gives this stacktrace.
This is the node.js file
and this is the script.py file
There is a ton of people with issues like this, however all the answers seem to be over specfic for the particular person. Some mentions path variables, some npm.cmd and others something third.
How should I work around this particular case?
I have tried npm init, npm install, fundling around moving pieces of code googling and changed scope of cmd and directory and so on.
2 Answers 2
Hey i had a similar problem and this did the trick , it was fixed when i added pythonPath: ‘python’ :
Hy I had similar error:
events.js:292 throw er; // Unhandled ‘error’ event ^
Error: spawn python ENOENT at Process.ChildProcess._handle.onexit (internal/child_process.js:267:19) at onErrorNT (internal/child_process.js:469:16) at processTicksAndRejections (internal/process/task_queues.js:84:21) Emitted ‘error’ event on ChildProcess instance at: at Process.ChildProcess._handle.onexit (internal/child_process.js:273:12) at onErrorNT (internal/child_process.js:469:16) at processTicksAndRejections (internal/process/task_queues.js:84:21) < errno: 'ENOENT', code: 'ENOENT', syscall: 'spawn python', path: 'python', spawnargs: [ '/home/NodeJsRunPython/script2.py' ] >
I change ‘python’ in ‘python3’ on
const python = spawn(‘python3′, [__dirname +’/script2.py’]);