子进程child_process让Node.js具备命令行的功能

Node中使用子进程的目的,正是希望从Node应用程序中通过命令行的方式访问计算机资源。

共有四种不同的技术来创建一个子进程

child_process.spawn

spawn是创建子进程最常见的方法。例:

var spawn = require('child_process').spawn,
    pwd = spawn('pwd');

pwd.stdout.on('data', function(data){
  console.log('stdout:' + data);
});

pwd.stderr.on('data', function(data){
  console.log('stderr' + data);
});

pwd.on('close', function(code){
  console.log('child process close with code' + code);
});

pwd.on('exit', function(code){
  console.log('child process exit with code' + code);
});
  • 参数作为数组传入
  • 子进程对 stdoutstderr 相关事件可以进行捕获
  • 子进程退出代码为 1,表示发生了错误;没有错误时,退出代码为 0
  • 尽量使用close事件而不是exit事件,在进程结束后访问其数据可能会导致应用程序崩溃

如何使用 stdin 标准输入对象呢:

var spawn = require('child_process').spawn,
    find = spawn('find', ['.', '-ls']),
    grep = spawn('grep', ['test']);

grep.stdout.setEncoding('utf8');

find.stdout.on('data', function(data){
  grep.stdin.write(data);
});

grep.stdout.on('data', function(data){
  console.log(data);
})

上面这段例子模拟了Unix管道(|)功能,可以将一个命令的结果传递给另一个命令作为输入。

child_process.exec 和 child_process.execFile

通过 child_process.execchild_process.execFile 来启动 shell 执行命令可以缓存命令执行的结果

child_process.execFile 的第一个参数是命令或执行文件路径, 第二个参数是可选参数列表, 第三个参数是回调函数,该回调函数有三个参数: error, stdout 和 stderr。如果没有发生错误,执行结果会保存到 stdout。

child_process.exec 则没有可选参数列表,只有 execFile 方法的第一个和第三个参数。

var execFile = require('child_process').execFile,
    child;

child = execFile('ls', ['-l'], function(error, stdout, stderr){
  if (error == null) {
    console.log('stdout: ' + stdout);
  }
});

execFile 方法会更安全,因为它的命令行参数作为数组传入。

child_process.fork

fork 其实是对 spawn的封装,目的是为了启动子进程并运行 Node.js模块。

例: fork('./child.js') 相当于 spawn('node', ['./child.js'])

此方法会在父进程与子进程之间建立一个真实的通信管道,用于进程之间的通信。但通过fork生成的每个子进程都需要一个全新的 V8 实例,这需要耗费更多时间和内存。

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

send 方法用于进程间通信, 通过监听message事件来获取消息

0%