`
wangyongfei
  • 浏览: 23174 次
  • 性别: Icon_minigender_1
文章分类
社区版块
存档分类
最新评论

node.js child_process模块

阅读更多

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

child_process模块的方法:

 

1.exec()   2.execSync()   3.execFile()   4.spawn()   5.fork()   6.send()

 

1.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方法。

 

2.execSync()方法:

 

execSync是exec的同步执行版本。

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

 

 

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。

 

3.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程序不理解它们的含义,因此也就得不到运行结果,安全性就得到了提高。

 

4.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])

 

 

5.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事件,并向父进程发送信息。

 

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

 

 

分享到:
评论

相关推荐

    node的process以及child_process模块学习笔记

    总结来说,`process`对象和`child_process`模块是Node.js进行进程管理和跨进程通信的关键工具,它们帮助开发者充分利用多核CPU资源,提高程序性能和稳定性。通过理解和熟练运用这些特性,可以编写出更高效、更健壮的...

    详解从Node.js的child_process模块来学习父子进程之间的通信

    Node.js的child_process模块是其标准库的一部分,它提供了丰富的接口来创建和管理子进程,使得父子进程间的通信成为可能。父子进程间的通信在多线程操作系统中是一种常见的进程间通信(IPC)方式,它允许主进程和它的...

    node.js中process进程的概念和child_process子进程模块的使用方法示例

    主要介绍了node.js中process进程的概念和child_process子进程模块的使用方法,结合实例形式分析了node.js中process进程和child_process子进程模块相关概念、原理、使用方法及操作注意事项,需要的朋友可以参考下

    child-process-ctor-Node.js4childProcess.ChildProcessponyfill.

    总结来说,`child-process-ctor-Node.js4childProcess.ChildProcessponyfill`是一个针对Node.js v4版本的`ChildProcess`构造函数的兼容性库,它允许开发者在旧版本Node.js环境中使用与新版本相同的方法来创建和管理...

    spawk:node.js child_process.spawn 模拟库

    此处的child将是一个模拟的 ChildProcess 对象,它将以状态代码 1 退出,并将在其 stdout 接口上接收字符串custom response 。 默认情况下,任何与现有模拟不匹配的spawn调用都将传递到原始spawn 。 有关如何更改...

    Node.js中的child_process模块详解

    在Node.js中,`child_process`模块是一个核心模块,它允许开发者创建和管理子进程。这个模块对于处理需要执行系统命令、运行外部程序或者进行CPU密集型计算等场景特别有用,因为Node.js本身是单线程的,处理这样的...

    使用promises的“child_process”模块的简单包装器_JavaScript_下载.zip

    在JavaScript的世界里,`child_process`模块是Node.js的核心模块之一,它允许开发者在Node.js应用中执行子进程,这通常用于运行系统命令或者与其他非JavaScript应用程序交互。然而,由于Node.js早期版本不支持...

    详解node child_process模块学习笔记

    Node.js 中的 Child Process 模块详解 Node.js 作为一个单进程的语言,不能像 Java 那样创建多线程来并发执行。为了充分利用 CPU 的多核机制,Node.js 提供了 Child Process 模块来创建多个进程。Child Process ...

    Node.js-exec-file-sync-Node.js0.12childProcess.execFileSync()ponyfill

    在Node.js环境中,`childProcess`模块是用于与子进程进行交互的核心模块,它提供了多种方法来执行外部命令行程序并获取其输出。在描述中提到的`execFileSync()`是其中一个同步版本的方法,用于在Node.js 0.12及更低...

    Node.js中child_process实现多进程

    为了解决这个问题,Node.js 提供了 child_process 模块,该模块允许开发者创建新的进程,从而利用多核 CPU 能力进行并行处理,尤其适合于耗时的计算任务。child_process 模块提供了几种方法来创建子进程,其中 fork...

    node-child-process-async:覆盖Node的child_process模块​​的最佳方法w Promises

    我们还是回到一个ChildProcess的实例,只需用.then()和.catch()添加到它,使其答应友好。 安装 npm install --save child-process-async 用法 // OLD: const { exec , spawn } = require ( 'child_process' ) ; // ...

    Node.js-PyNode-从node.js调用python代码

    这个桥梁通常是由第三方库提供的,比如`child_process`模块(Node.js内置)或者`python-shell`库。`child_process`允许我们直接执行Python脚本并捕获其输出,而`python-shell`库则提供了一个更高级的接口,使交互式...

    4-child_process (子进程).pdf

    在Node.js中,`child_process`模块是用于创建和管理子进程的核心模块,它提供了多种方式来执行外部程序,如操作系统命令或者独立的Node.js进程。这个模块在互联网开发中非常常见,因为开发者经常需要与操作系统进行...

    Node.js-Node.js实现Git分布式自动化部署系统

    5. **Node.js与Git交互**:使用Node.js的child_process模块调用Git命令,实现从读取改动到执行部署的自动化流程。 6. **持续集成/持续部署(CI/CD)**:了解Jenkins、Travis CI、GitHub Actions等CI/CD工具,它们可以...

    node-process, node.js 和浏览器的进程信息.zip

    node-process, node.js 和浏览器的进程信息 进程require('process'); 与其他模块一样。通过模块提供的browser.js shim 在 node.js 和浏览器中工作。浏览器实现这个 MODULE的目标并非是内置进程 MODULE的完全成熟的...

Global site tag (gtag.js) - Google Analytics