spawn/fork/exce/exceFIil区别
spawn
启动子进程来执行命令的基础方法,其他方法都是对该方法的封装。不支持回调,只能通过data事件来获取数据。
fork
fork用于直接执行nodejs文件, 并且父子进程建立一个IPC通道。
//parent.js
const cp = require('child_process');
const n = cp.fork(`${__dirname}/sub.js`);
n.on('message', (m) => {
console.log('PARENT got message:', m);
});
n.send({ hello: 'world' });
//sub.js
process.on('message', (m) => {
console.log('CHILD got message:', m);
});
process.send({ foo: 'bar' });
exce
通过新建shell子进程来执行命令,通过callback获取数据
const exec = require('child_process').exec;
exec('for i in $( ls -LR ); do echo item: $i; done', (e, stdout, stderr)=> {
if (e instanceof Error) {
console.error(e);
throw e;
}
console.log('stdout ', stdout);
console.log('stderr ', stderr);
});
const exec = require('child_process').exec;
exec('netstat -aon | find "9000"', (e, stdout, stderr)=> {
if (e instanceof Error) {
console.error(e);
throw e;
}
console.log('stdout ', stdout);
console.log('stderr ', stderr);
});
execFile
直接调用命令,通过callback获取数据
const execFile = require('child_process').execFile;
const child = execFile('node', ['--version'], (error, stdout, stderr) => {
if (error) {
console.error('stderr', stderr);
throw error;
}
console.log('stdout', stdout);
});
同一个命令,不同调用方式:
// spawm 模式
child = child_process.spawn('ls', ['-lh', '/usr']);
child.stdout.setEncoding('utf8');
child.stdout.on('data', function(data) {
console.log(data);
});
// exec 模式
child_process.exec('ls -lh /usr', function(err, stdout, stderr) {
console.log(stdout);
});
// execFile 模式
child = child_process.execFile('ls', ['-lh', '/usr'], function(err, stdout, stderr) {
console.log(stdout);
});
创建子进程
options.stdio
pipe
: 相当于[“pipe”,“pipe”,“pipe”],子进程的stdio与父进程的stdio通过管道连接起来,ignore
: 相当于[“ignore”,“ignore”,“ignore”],子进程的stdio绑定到/dev/null
,丢弃数据的输入输出inherit
: 继承于父进程的相关stdio、即等同于[process.stdin, process.stdout, process.stderr]
或者[0,1,2]
,此时父子进程的stdio都是绑定到同一个地方。参考
child_process和IPC探究(标题党,其实并没有IPC)