Child process module of NodeJS

Keywords: shell

Article directory

1 Child Process module

1.1 INTRODUCTION

The child process module is used to create a new child process. The running results of the subprocesses are stored in the system cache (maximum 200KB). After the subprocesses run, the main process uses the callback function to read the running results of the subprocesses.

1.2 method

1.2.1 exec()

The exec method is used to execute bash commands, and its argument is a command string.

var exec = require('child_process').exec;
var ls = exec('ls -l', function (error, stdout, stderr) {
  if (error) {
    console.log(error.stack);
    console.log('Error code: ' + error.code);
  }
  console.log('Child Process STDOUT: ' + stdout);
});

The exec method in the above code is used to create a new subprocess, cache its running results, and call the callback function after the running.
The exec method can accept at most two parameters. The first parameter is the shell command to be executed, and the second parameter is the callback function. The function accepts three parameters, namely, the error occurred, the display result of standard output, and the display result of standard error.
Since both standard output and standard error are stream objects, you can listen to data events, so the above code can also be written as follows.

var exec = require('child_process').exec;
var child = exec('ls -l');

child.stdout.on('data', function(data) {
  console.log('stdout: ' + data);
});
child.stderr.on('data', function(data) {
  console.log('stdout: ' + data);
});
child.on('close', function(code) {
  console.log('closing code: ' + code);
});

The above code also shows that the subprocess itself has a close event, and the callback function can be set.
The code above has another benefit. After listening to the data event, you can output the result in real time. Otherwise, the result will not be output until the end of the subprocess. Therefore, if the subprocess runs for a long time or continuously, the second method is better.
Here's another example, assuming you have a child.js file.

// child.js
var exec = require('child_process').exec;
exec('node -v', function(error, stdout, stderr) {
  console.log('stdout: ' + stdout);
  console.log('stderr: ' + stderr);
  if (error !== null) {
    console.log('exec error: ' + error);
  }
});

After running, the output of the file is as follows.

$ node child.js
stdout: v0.11.14
stderr:

Exec method will directly call bash (/ bin/sh program) to interpret the command, so if there are user input parameters, exec method is not safe.

var path = ";user input";
child_process.exec('ls -l ' + path, function (err, data) {
  console.log(data);
});

The above code indicates that in bash environment, ls -l; user input will run directly. If users enter malicious code, it will bring security risks. Therefore, in the case of user input, it is better not to use the exec method, but the execFile method.

1.2.2 execFile()

The execFile method directly executes specific programs. Parameters are passed in as arrays and will not be interpreted by bash, so it has high security.

var child_process = require('child_process');

var path = ".";
child_process.execFile('/bin/ls', ['-l', path], function (err, result) {
    console.log(result)
});

In the above code, assume that the path comes from user input. If it contains semicolons or backquotes, the ls program does not understand their meaning, so it will not get running results, and the security will be improved.

1.2.3 spawn()

The spawn method creates a subprocess to execute specific commands, which is similar to the execFile method, but there is no callback function, so you can only get the running results by listening to events. It belongs to asynchronous execution, and is suitable for long-time running of subprocesses.

var child_process = require('child_process');
var path = '.';
var ls = child_process.spawn('/bin/ls', ['-l', path]);
ls.stdout.on('data', function (data) {
  console.log('stdout: ' + data);
});
ls.stderr.on('data', function (data) {
  console.log('stderr: ' + data);
});
ls.on('close', function (code) {
  console.log('child process exited with code ' + code);
});

The spawn method takes two parameters, the first is an executable and the second is an array of parameters.
The spawn object returns an object that represents a child process. This object deploys the EventEmitter interface. Its data events can be monitored to get the output of subprocesses.
The spawn method is very similar to the exec method, except for the slightly different format.

child_process.exec(command, [options], callback)
child_process.spawn(command, [args], [options])

1.2.4 fork()

The fork method creates a subprocess directly and executes the Node script. The fork('. / child.js') is equivalent to the spawn('node', ['./child.js'). Unlike the spawn method, fork establishes a communication channel between the parent process and the child process for the communication between the processes.

var n = child_process.fork('./child.js');
n.on('message', function(m) {
  console.log('PARENT got message:', m);
});
n.send({ hello: 'world' });

In the above code, the fork method returns an object that represents the inter process communication channel. For this object, you can listen to message events to get the information returned by sub processes, or send information to sub processes.
The content of the child.js script is as follows.

process.on('message', function(m) {
  console.log('CHILD got message:', m);
});
process.send({ foo: 'bar' });

In the above code, the child process listens for the message event and sends information to the parent process.

1.2.5 send()

After the new process is generated by using child? Process. Fork(), you can send messages to the new process by using child.send(message, [sendHandle]). In the new process, the message is obtained by listening for the message event.
The following example is the main process code.

var cp = require('child_process');

var n = cp.fork(__dirname + '/sub.js');

n.on('message', function(m) {
  console.log('PARENT got message:', m);
});

n.send({ hello: 'world' });

The following is the sub.js code of the subprocess.

process.on('message', function(m) {
  console.log('CHILD got message:', m);
});

process.send({ foo: 'bar' });

Posted by frizzo on Sat, 26 Oct 2019 19:46:18 -0700