目录

child_process模块用于新建子进程。子进程的运行结果储存在系统缓存之中(最大200KB),等到子进程运行结束以后,主进程再用回调函数读取子进程的运行结果。

exec()

exec方法用于执行bash命令,它的参数是一个命令字符串。

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);
});

上面代码的exec方法用于新建一个子进程,然后缓存它的运行结果,运行结束后调用回调函数。

exec方法最多可以接受两个参数,第一个参数是所要执行的shell命令,第二个参数是回调函数,该函数接受三个参数,分别是发生的错误、标准输出的显示结果、标准错误的显示结果。

由于标准输出和标准错误都是流对象(stream),可以监听data事件,因此上面的代码也可以写成下面这样。

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);
});

上面的代码还表明,子进程本身有close事件,可以设置回调函数。

上面的代码还有一个好处。监听data事件以后,可以实时输出结果,否则只有等到子进程结束,才会输出结果。所以,如果子进程运行时间较长,或者是持续运行,第二种写法更好。

下面是另一个例子,假定有一个child.js文件。

// 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);
}
});

运行后,该文件的输出结果如下。

$ node child.js

stdout: v0.11.14

stderr:

exec方法会直接调用bash(/bin/sh程序)来解释命令,所以如果有用户输入的参数,exec方法是不安全的。

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

上面代码表示,在bash环境下,ls -l; user input会直接运行。如果用户输入恶意代码,将会带来安全风险。因此,在有用户输入的情况下,最好不使用exec方法,而是使用execFile方法。

execSync()

execSyncexec的同步执行版本。

它可以接受两个参数,第一个参数是所要执行的命令,第二个参数用来配置执行环境。

var execSync = require("child_process").execSync;

var SEPARATOR = process.platform === 'win32' ? ';' : ':';
var env = Object.assign({}, process.env); env.PATH = path.resolve('./node_modules/.bin') + SEPARATOR + env.PATH; function myExecSync(cmd) {
var output = execSync(cmd, {
cwd: process.cwd(),
env: env
}); console.log(output);
} myExecSync('eslint .');

上面代码中,execSync方法的第二个参数是一个对象。该对象的cwd属性指定脚本的当前目录,env属性指定环境变量。上面代码将./node_modules/.bin目录,存入$PATH变量。这样就可以不加路径,引用项目内部的模块命令了,比如eslint命令实际执行的是./node_modules/.bin/eslint

execFile()

execFile方法直接执行特定的程序,参数作为数组传入,不会被bash解释,因此具有较高的安全性。

var child_process = require('child_process');

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

上面代码中,假定path来自用户输入,如果其中包含了分号或反引号,ls程序不理解它们的含义,因此也就得不到运行结果,安全性就得到了提高。

spawn()

spawn方法创建一个子进程来执行特定命令,用法与execFile方法类似,但是没有回调函数,只能通过监听事件,来获取运行结果。它属于异步执行,适用于子进程长时间运行的情况。

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);
});

spawn方法接受两个参数,第一个是可执行文件,第二个是参数数组。

spawn对象返回一个对象,代表子进程。该对象部署了EventEmitter接口,它的data事件可以监听,从而得到子进程的输出结果。

spawn方法与exec方法非常类似,只是使用格式略有区别。

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

fork()

fork方法直接创建一个子进程,执行Node脚本,fork('./child.js') 相当于 spawn('node', ['./child.js']) 。与spawn方法不同的是,fork会在父进程与子进程之间,建立一个通信管道,用于进程之间的通信。


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

上面代码中,fork方法返回一个代表进程间通信管道的对象,对该对象可以监听message事件,用来获取子进程返回的信息,也可以向子进程发送信息。

child.js脚本的内容如下。


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

上面代码中,子进程监听message事件,并向父进程发送信息。

send()

使用 child_process.fork() 生成新进程之后,就可以用 child.send(message, [sendHandle]) 向新进程发送消息。新进程中通过监听message事件,来获取消息。

下面的例子是主进程的代码。

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' });

下面是子进程sub.js代码。

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

参考链接

from:http://javascript.ruanyifeng.com/nodejs/child-process.html

Child Process模块的更多相关文章

  1. node中非常重要的process对象,Child Process模块

    node中非常重要的process对象,Child Process模块Child Process模块http://javascript.ruanyifeng.com/nodejs/child-proc ...

  2. nodejs-Child Process模块

    JavaScript 标准参考教程(alpha) 草稿二:Node.js Child Process模块 GitHub TOP Child Process模块 来自<JavaScript 标准参 ...

  3. Child Process

    Child Process child_process 这个模块可以生成一个子进程.nodejs提供了好几个API,本质上都是调用child_process.spawn(): const spawn ...

  4. Node: Process模块 (Features of Process)

    Process模块 (Features of Process) process is a global variable which indicates the current Node.js pro ...

  5. 在nodejs中创建child process

    目录 简介 child process 异步创建进程 同步创建进程 在nodejs中创建child process 简介 nodejs的main event loop是单线程的,nodejs本身也维护 ...

  6. Node.js process 模块常用属性和方法

    Node.js是常用的Javascript运行环境,本文和大家发分享的主要是Node.js中process 模块的常用属性和方法,希望通过本文的分享,对大家学习Node.js http://www.m ...

  7. wireshark_Couldn’t run /usr/sbin/dumpcap in child process: Permission denied

    关于Wireshark出现:Couldn't run /usr/sbin/dumpcap in child process: Permission denied Are you a member of ...

  8. innobackupex:Error:xtrabackup child process has died at /usr/bin/innobackupex

    使用innobackupex进行数据库备份,报如下错误:innobackupex --compress --parallel=4  --user=root  --password=yoon /expo ...

  9. Node.js的process模块

    process模块用来与当前进程互动,可以通过全局变量process访问,不必使用require命令加载.它是一个EventEmitter对象的实例. 属性 process对象提供一系列属性,用于返回 ...

随机推荐

  1. 沉迷Link-Cut tree无法自拔之:[BZOJ2049]洞穴勘探(蒟蒻的LCT板子)

    来自蒟蒻 \(Hero \_of \_Someone\) 的 \(LCT\) 学习笔记 最近学了一波 \(LCT\) , 于是怒刷 \(LCT\) 合集...... $ $ 学的时候借鉴了 Clove ...

  2. BZOJ 5308 [ZJOI2018] Day2T2 胖 | 二分 ST表

    题目链接 LOJ 2529 BZOJ 5308 题解 这么简单的题 为什么考场上我完全想不清楚 = = 对于k个关键点中的每一个关键点\(a\),二分它能一度成为哪些点的最短路起点(显然这些点在一段包 ...

  3. SharePoint 2013 APP 开发示例 (五)跨域访问 Web Service (REST API)

          虽然 JQuery 也能通过授权header实现跨域, 但SharePoint 提供了更简单的方法,它被实现在SP.RequestExecutor里 .它能访问跨域的服务包括REST AP ...

  4. 【洛谷P1091】合唱队列

    题目大意:给定一个有 N 个正整数的序列,从其中拿走一些数,使得剩下的数满足严格单峰性,即先严格递增后严格递减,允许单调增和单调减,求最少需要拿走多少数. 题解:先考虑严格单调的情况,最少需要拿走多少 ...

  5. 【POJ3349】snowflakes

    这是一道可以练习哈希表的模板题.关于哈希表的操作均有涉及. 哈希函数的选取是这道题的关键.这道题的关键字是一个长度为6的序列,并且序列与开始顺序.时钟顺序均无关. 因此,采用哈希函数\(H[x]=\S ...

  6. 【数学】NOIP数论内容整理

    NOIP数论内容整理 注:特别感谢sdsy的zxy神仙以及lcez的tsr筮安帮助审稿 一.整除: 对于\(a,b~\in~Z\),若\(\exists~k~\in~Z\),\(s.t.~b~=~k~ ...

  7. MATLAB:图像减法运算(imsubtract函数)

    图像减法运行涉及到imsubtract函数 实现代码如下: clear all; %关闭当前所有图形窗口,清空工作空间变量,清除工作空间所有变量 clc close all; A=imread('ca ...

  8. NO.7:别让异常逃离析构函数

    1.析构函数绝对不要吐出异常,如果一个析构函数可能抛出异常,析构函数应该捕获任何异常,然后要么吞下它们或者退出程序 2.如果用户需要对析构内的可能抛出异常的操作做出反应,则应该将操作放入除析构函数外的 ...

  9. 线程池之ThreadPoolExecutor

    所属包: java.util.concurrent.ThreadPoolExecutor 类关系: public class ThreadPoolExecutor extends AbstractEx ...

  10. linux 空间释放,mysql数据库空间释放

    测试告急,服务器不行了.down了…… 1.linux如何查看磁盘剩余空间: [root@XXX~]# df -lhFilesystem        Size      Used      Avai ...