Reputation: 100210
I have a Node.js process and this process forks an sh
child process to run a bash script. Something like this:
const cp = require('child_process');
const n = cp.spawn('sh',['foo.sh'], {
stdio: ['ignore','ignore','ignore','ipc']
});
in my bash script (foo.sh), how can I send an IPC message back to the Node.js parent process? Cannot find out how to do that.
Doing some more research, looks like I will be getting closer to the IPC internals. One thing that might help is if I pass the parent PID to the bash script, then maybe I can do something with that.
Upvotes: 4
Views: 2479
Reputation: 1085
When you add 'ipc'
to your stdio
options, the parent process and child process will establish a communication channel, and provide a file descriptor for the child process to use. This descriptor will be defined in your environment as $NODE_CHANNEL_FD
. You can redirect output to this descriptor and it will be sent to the parent process to be parsed and handled.
As a simple example, I sent my name from the bash script to the parent process to be logged.
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
Essentially what is happening in the bash file is:
printf
command to send the JSON to stdout
, file descriptor 1.$NODE_CHANNEL_FD
Note that the JSON you send must be properly formatted and terminated with a
\n
character
If you wanted to send data from the parent process to the bash process you could add
n.send({"message": "hello world"});
to your JavaScript, and in the bash file you could use something along the lines of
MESSAGE=read -u $NODE_CHANNEL_FD
echo " => message from parent process => $MESSAGE"
Note that you will have to change your
stdio
options so that you are not ignoring the standard output of the child process. You could set them to['ignore', 1, 'ignore', 'ipc']
so that the child process' standard output goes straight to the parent's.
Upvotes: 6