在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);
});
- 参数作为数组传入
- 子进程对
stdout
和stderr
相关事件可以进行捕获 - 子进程退出代码为 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.exec
和 child_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
事件来获取消息