admin管理员组

文章数量:1305023

Being inside of a NodeJS process, how can I listen for events from bash?

For example

NodeJS side

obj.on("something", function (data) {
   console.log(data);
});

Bash side

$ do-something 'Hello World'

Then in the NodeJS stdout will appear "Hello World" message.

How can I do this?

I guess it's related to signal events.

Being inside of a NodeJS process, how can I listen for events from bash?

For example

NodeJS side

obj.on("something", function (data) {
   console.log(data);
});

Bash side

$ do-something 'Hello World'

Then in the NodeJS stdout will appear "Hello World" message.

How can I do this?

I guess it's related to signal events.

Share Improve this question asked Jun 25, 2014 at 14:33 Ionică BizăuIonică Bizău 113k93 gold badges307 silver badges487 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 8 +50

The problem with using signals is that you can't pass arguments and most of them are reserved for system use already (I think SIGUSR2 is really the only safe one for node since SIGUSR1 starts the debugger and those are the only two that are supposed to be for user-defined conditions).

Instead, the best way that I've found to do this is by using UNIX sockets; they're designed for inter process munication.

The easiest way to setup a UNIX socket in node is by setting up a standard net server with net.createServer() and then simply passing a file path to server.listen() to create the socket at the path you specified. Note: It's important that a file at that path doesn't exist, otherwise you'll get a EADDRINUSE error.

Something like this:

var net = require('net');

var server = net.createServer(function(connection) {
    connection.on('data', function(data) {
        // data is a Buffer, so we'll .toString() it for this example
        console.log(data.toString());
    });
});

// This creates a UNIX socket in the current directory named "nodejs_bridge.sock"
server.listen('nodejs_bridge.sock');

// Make sure we close the server when the process exits so the file it created is removed
process.on('exit', function() {
    server.close();
});

// Call process.exit() explicitly on ctl-c so that we actually get that event
process.on('SIGINT', function() {
    process.exit();
});

// Resume stdin so that we don't just exit immediately
process.stdin.resume();

Then, to actually send something to that socket in bash, you can pipe to nc like this:

echo "Hello World" | nc -U nodejs_bridge.sock

What about using FIFOs?

NodeJS code:

process.stdin.on('readable', function() {
  var chunk = process.stdin.read();
  if (chunk !== null) {
    process.stdout.write('data: ' + chunk);
  }
});

NodeJS startup (the 3>/tmp/... is a trick to keep FIFO open):

mkfifo /tmp/nodeJsProcess.fifo
node myProgram.js </tmp/nodeJsProcess.fifo 3>/tmp/nodeJsProcess.fifo

Bash linkage:

echo Hello >/tmp/nodeJsProcess.fifo

The signals described in the page that you've linked are used to send some specific "mand" to processes. This is called "Inter Process Communication". You can see here a first definition of IPC.

You can instruct you node.js code to react to a specific signal, as in this example:

// Start reading from stdin so we don't exit.
process.stdin.resume();

process.on('SIGUSR1', function() {
  console.log('Got SIGUSR1.  Here you can do something.');
});

Please note that the signal is sent to the process, and not to a specific object in the code.

If you need to municate in a more specific way to the node.js daemon you can listen on another port too, and use it to receive (and eventually send) control mands.

本文标签: javascriptListening for outside events Bash to NodeJS bridgeStack Overflow