2016-12-08 4 views
1

У меня есть процесс Node.js, и этот процесс создает дочерний процесс sh для запуска сценария bash. Что-то вроде этого:Отправить сообщение IPC с sh/bash в родительский процесс (Node.js)

const cp = require('child_process'); 

const n = cp.spawn('sh',['foo.sh'], { 
    stdio: ['ignore','ignore','ignore','ipc'] 
}); 

в моей Баш скрипт (foo.sh), как я могу отправить сообщение IPC обратно в родительский процесс Node.js? Не могу узнать, как это сделать.

Выполнение еще нескольких исследований, похоже, я буду ближе к внутренним IPC. Одна вещь, которая может помочь, заключается в том, что я передаю родительский PID сценарию bash, тогда, возможно, я смогу что-то сделать с этим.

+0

http://stackoverflow.com/questions/10213501/communicating-between-two-different-processes-in-node-js - это ваш случай? – Andrey

+0

нет, это два процесса node.js. Я говорю о процессе node.js и процессе sh/bash. Я не знаю, как делать вызовы IPC в bash. –

+0

Я сомневаюсь, что вы захотите использовать механизм IPC узла, если дочерний процесс не является процессом узла. В противном случае вам придется реализовать протокол IPC JSON узла в bash, и этот протокол не является общедоступным, поэтому он может измениться. – mscdex

ответ

2

При добавлении 'ipc' в параметры stdio родительский процесс и дочерний процесс устанавливают канал связи и предоставляют файловый дескриптор для дочернего процесса. Этот дескриптор будет определен в вашей среде как $NODE_CHANNEL_FD. Вы можете перенаправить вывод в этот дескриптор, и он будет отправлен в родительский процесс, который будет разбираться и обрабатываться.

Как простой пример, я отправил свое имя из сценария bash в родительский процесс для регистрации.

index.js

const cp = require('child_process'); 
const n = cp.spawn('sh', ['foo.sh'], { 
    stdio: ['ignore', 'ignore', 'ignore', 'ipc'] 
}); 

n.on('message', (data) => { 
    console.log('name: ' + data.name); 
}); 

foo.sh

printf "{\"name\": \"Craig\"}\n" 1>&$NODE_CHANNEL_FD 

По сути то, что происходит в файле Баш:

  1. Я использую printf команду отправить JSON на stdout, дескриптор файла 1.
  2. А затем перенаправляет его к ссылке (&) из $NODE_CHANNEL_FD

Обратите внимание, что JSON вы отправляете должны быть надлежащим образом отформатированный и прекращается с \n характером

Если вы хотите отправить данные из родительского процесса в процесс bash вы можете добавить

n.send({"message": "hello world"}); 

к вашему JavaScript, и в файле Баш вы могли бы использовать что-то вдоль линий

MESSAGE=read -u $NODE_CHANNEL_FD 
echo " => message from parent process => $MESSAGE" 

Обратите внимание, что вам придется изменить свои stdio варианты, так что вы не обращая внимания на стандартный вывод детского процесса. Вы можете установить их на ['ignore', 1, 'ignore', 'ipc'], чтобы стандартный выход дочернего процесса шел прямо к родительскому.

+0

Отлично, спасибо Craig –

+0

Одна вещь, с которой я смущен, заключается в том, как сценарий bash ожидает получения сообщения от родителя ? Другими словами, будет ли команда read -u ждать следующего сообщения или она просто вернется пустым, если нет сообщения? –

+0

В .js довольно ясно, как это сделать, вы регистрируете обратный вызов, и любые последующие сообщения будут получены, но это не так, как работает bash TMK –