[朝花夕拾]关于nodejs中child_process之中spawn和exec的区别
2016-06-14 23:57
645 查看
近日整理以前的node项目时发现一个文件同时声明了spawn和exec两种方法。最后只是用了spawn方法,所以查了一下这两者的区别。
Nodejs基于事件驱动来处理并发,本身是单线程模式运行的。Nodejs通过使用child_process模块来生成多个子进程来处理其他事物。主要包括4个异步进程函数(spawn,exec,execFile,fork)和3个同步进程函数(spawnSync,execFileSync,execSync)。以异步函数中spawn是最基本的创建子进程的函数,其他三个异步函数都是对spawn不同程度的封装。spawn只能运行指定的程序,参数需要在列表中给出,而exec可以直接运行复杂的命令。
比如要运行 du -sh /disk1 命令, 使用spawn函数需要写成spawn(‘du‘, [‘-sh ‘, ‘/disk1’]),而使用exec函数时,可以直接写成exec(‘du -sh /disk1’)。exec是会先进行Shell语法解析,因此用exec函数可以更方便的使用复杂的Shell命令,包括管道、重定向等。
一,var exec =require('child_process').exec;
exec在子进程输出结果将放入buffer中,在结果返回完全之后,再将输出一次性地以回调函数参数的形式返回。如果exec的buffer体积设置的不够大,它将会以一个“maxBuffer exceeded”错误失败告终。另外,exec函数是对spawn的一种友好封装,增加Shell命令解析,可以直接嵌入复杂的命令
a) 语法:child_process.exec(command[, options], callback)
b) 实例:
// 使用wget下载文件的函数
vardownload_file_wget = function(file_url) {
// 提取文件名
var file_name =url.parse(file_url).pathname.split('/').pop();
// 组合wget命令
var wget = 'wget -P ' + DOWNLOAD_DIR + ' ' +file_url;
// 使用exec执行wget命令
var child = exec(wget, function(err, stdout,stderr) {
if (err) throw err;
else console.log(file_name + ' downloadedto ' + DOWNLOAD_DIR);
});
};
//执行cat统计文件
varchildProcess = require('child_process');
var ls =childProcess.exec('cat *.js | wc', function (error, stdout, stderr) {
if (error) {
console.log(error.stack);
console.log('Error code: '+error.code);
}
console.log('Child Process STDOUT:'+stdout);
});
二,var spawn =require('child_process').spawn;
spawn在子线程开始执行后,就开始不断将数据从子进程返回给主进程。从语法中我们可以发现与exec的一个区别是spawn是不支持callback函数的,它通过流的方式发数据传给主进程,从而实现了多进程之间的数据交换。这个功能的直接用应用场景就是“系统监控”。在Linux下,我们有很多命令行工具,可以实时监控CPU,内存,IO,网络等数据,那么用Node的child_process模块可以很容易地把这些数据采集的我们自己的应用中。
a) 语法:child_process.spawn(command[, args][, options])
b) 实例:
//这个实例就是所做的项目中nodejs实现堡垒机中生成子线程远程登录的方法
Var worker = spawn('telnet', ['202.198.0.123']);
client.telnet = worker.stdin;
worker.on('close', function (code){
client.fileWriteStream.end();
//client.status = 2;
client.socket.write('\n\r');
client.socket.write('[Common]');
client.socket.write('[INFO] :Connection to Device has closed!\n\r');
closeSocket(client.socket,client);
client.socket.destroy();
});
worker.stdout.on('data', function(data) {
data = data.toString();
if(client.status == 3){
return;
}
if((data.indexOf('nmslogin')>=0)&&(client.isLogin==0)){
client.secret = 1;
client.telnet.write('username\n');
}elseif((data.indexOf('Password')>=0)&&(client.isLogin==0)){
client.telnet.write('password\n');
client.isLogin = 1;
}elseif(data.indexOf('Password')>=0&& client.status == 4){
client.notChange= 1;
client.fileWriteStream.write(data);
client.socket.write(data);
client.datas =client.datas+data.toString();
}else {
client.fileWriteStream.write(data);
client.socket.write(data);
client.datas =client.datas+data.toString();
}
});
worker.on('error',function(error){
client.fileWriteStream.end();
client.status = 2;
client.socket.write('[ERR2] :Anerror occured!')
client.socket.write('[INFO] :Connection to Device has closed!\n\r');
//client.socket.write('>>>>Input Device IP:');
closeSocket(client.socket,client);
});
扩展阅读:
JavaScript 运行机制详解:再谈Event Loop
http://www.ruanyifeng.com/blog/2014/10/event-loop.html
Node.js软肋之回调大坑
http://www.infoq.com/cn/articles/nodejs-callback-hell
Node.js的线程和进程
http://www.admin10000.com/document/4196.html
http://rickgaribay.net/archive/2012/01/28/node-is-not-single-threaded.aspx
Linux下同步模式、异步模式、阻塞调用、非阻塞调用总结
http://www.360doc.com/content/13/0117/12/5073814_260691714.shtml
Nodejs基于事件驱动来处理并发,本身是单线程模式运行的。Nodejs通过使用child_process模块来生成多个子进程来处理其他事物。主要包括4个异步进程函数(spawn,exec,execFile,fork)和3个同步进程函数(spawnSync,execFileSync,execSync)。以异步函数中spawn是最基本的创建子进程的函数,其他三个异步函数都是对spawn不同程度的封装。spawn只能运行指定的程序,参数需要在列表中给出,而exec可以直接运行复杂的命令。
比如要运行 du -sh /disk1 命令, 使用spawn函数需要写成spawn(‘du‘, [‘-sh ‘, ‘/disk1’]),而使用exec函数时,可以直接写成exec(‘du -sh /disk1’)。exec是会先进行Shell语法解析,因此用exec函数可以更方便的使用复杂的Shell命令,包括管道、重定向等。
一,var exec =require('child_process').exec;
exec在子进程输出结果将放入buffer中,在结果返回完全之后,再将输出一次性地以回调函数参数的形式返回。如果exec的buffer体积设置的不够大,它将会以一个“maxBuffer exceeded”错误失败告终。另外,exec函数是对spawn的一种友好封装,增加Shell命令解析,可以直接嵌入复杂的命令
a) 语法:child_process.exec(command[, options], callback)
b) 实例:
// 使用wget下载文件的函数
vardownload_file_wget = function(file_url) {
// 提取文件名
var file_name =url.parse(file_url).pathname.split('/').pop();
// 组合wget命令
var wget = 'wget -P ' + DOWNLOAD_DIR + ' ' +file_url;
// 使用exec执行wget命令
var child = exec(wget, function(err, stdout,stderr) {
if (err) throw err;
else console.log(file_name + ' downloadedto ' + DOWNLOAD_DIR);
});
};
//执行cat统计文件
varchildProcess = require('child_process');
var ls =childProcess.exec('cat *.js | wc', function (error, stdout, stderr) {
if (error) {
console.log(error.stack);
console.log('Error code: '+error.code);
}
console.log('Child Process STDOUT:'+stdout);
});
二,var spawn =require('child_process').spawn;
spawn在子线程开始执行后,就开始不断将数据从子进程返回给主进程。从语法中我们可以发现与exec的一个区别是spawn是不支持callback函数的,它通过流的方式发数据传给主进程,从而实现了多进程之间的数据交换。这个功能的直接用应用场景就是“系统监控”。在Linux下,我们有很多命令行工具,可以实时监控CPU,内存,IO,网络等数据,那么用Node的child_process模块可以很容易地把这些数据采集的我们自己的应用中。
a) 语法:child_process.spawn(command[, args][, options])
b) 实例:
//这个实例就是所做的项目中nodejs实现堡垒机中生成子线程远程登录的方法
Var worker = spawn('telnet', ['202.198.0.123']);
client.telnet = worker.stdin;
worker.on('close', function (code){
client.fileWriteStream.end();
//client.status = 2;
client.socket.write('\n\r');
client.socket.write('[Common]');
client.socket.write('[INFO] :Connection to Device has closed!\n\r');
closeSocket(client.socket,client);
client.socket.destroy();
});
worker.stdout.on('data', function(data) {
data = data.toString();
if(client.status == 3){
return;
}
if((data.indexOf('nmslogin')>=0)&&(client.isLogin==0)){
client.secret = 1;
client.telnet.write('username\n');
}elseif((data.indexOf('Password')>=0)&&(client.isLogin==0)){
client.telnet.write('password\n');
client.isLogin = 1;
}elseif(data.indexOf('Password')>=0&& client.status == 4){
client.notChange= 1;
client.fileWriteStream.write(data);
client.socket.write(data);
client.datas =client.datas+data.toString();
}else {
client.fileWriteStream.write(data);
client.socket.write(data);
client.datas =client.datas+data.toString();
}
});
worker.on('error',function(error){
client.fileWriteStream.end();
client.status = 2;
client.socket.write('[ERR2] :Anerror occured!')
client.socket.write('[INFO] :Connection to Device has closed!\n\r');
//client.socket.write('>>>>Input Device IP:');
closeSocket(client.socket,client);
});
扩展阅读:
JavaScript 运行机制详解:再谈Event Loop
http://www.ruanyifeng.com/blog/2014/10/event-loop.html
Node.js软肋之回调大坑
http://www.infoq.com/cn/articles/nodejs-callback-hell
Node.js的线程和进程
http://www.admin10000.com/document/4196.html
http://rickgaribay.net/archive/2012/01/28/node-is-not-single-threaded.aspx
Linux下同步模式、异步模式、阻塞调用、非阻塞调用总结
http://www.360doc.com/content/13/0117/12/5073814_260691714.shtml
相关文章推荐
- ruby实现的一个异步文件下载HttpServer实例
- 使用ruby部署工具mina快速部署nodejs应用教程
- C#异步绑定数据实现方法
- C#线程间不能调用剪切板的解决方法
- 科学知识:同步、异步、阻塞和非阻塞区别
- 探讨Ajax中同步与异步之间的区别
- C#线程同步的三类情景分析
- C#获取进程或线程相关信息的方法
- 简单对比C#程序中的单线程与多线程设计
- C#停止线程的方法
- C#子线程更新UI控件的方法实例总结
- C#线程队列用法实例分析
- C#中异步回调函数用法实例
- Google官方支持的NodeJS访问API,提供后台登录授权
- 浅谈Nodejs观察者模式
- nodejs教程之环境安装及运行
- nodejs中的fiber(纤程)库详解
- 基于NodeJS的前后端分离的思考与实践(五)多终端适配
- 基于NodeJS的前后端分离的思考与实践(二)模版探索
- 实例详解Nodejs 保存 payload 发送过来的文件