调用系统命令的方法分享,js中创建和管理外部进
分类:关于美高梅

Node被设计用来急速的拍卖I/O操作,不过你应当明了,有个别项目标主次并不相符这种形式。比方,假若你准备用Node管理三个CPU密集的天职,你大概会堵塞事件循环,并为此下降了程序的响应。替代格局是,把CPU密集的职分分配给三个独门的进度来拍卖,进而释放事件循环。Node允许你生出进程,并把那个新进度做为它父进度的子进程。在Node里,子进程能够和父进度进行双向通讯,並且在某种程度上,父进程还足以监督和管理子进度。

Node.js中创设和管理外界进度详解,node.js详解

Node被设计用来火速的拍卖I/O操作,但是你应当明了,某些项指标主次并不相符这种格局。比如,就算你计划用Node管理一个CPU密集的天职,你恐怕会堵塞事件循环,并据此下落了程序的响应。取代格局是,把CPU密集的职责分配给多少个单身的长河来拍卖,进而释放事件循环。Node允许你生出进程,并把那个新进程做为它父进度的子进度。在Node里,子进程能够和父进程进行双向通信,而且在某种程度上,父进度还能监督和管理子进度。

别的一种必要使用子进度的情形是,当你想大约地实行三个外界命令,并让Node获取命令的回到值时。比方,你能够施行二个UNIX命令、脚本大概别的那么些不能够在Node里直接施行的指令。

本章将向你显得什么进行外界命令,创制,并和子进程通讯,以及终结子进度。器重是让你领悟怎么着在Node进程外产生一层层职务。

实行外界命令

当你需求施行一个外界shell命令或可实践文件时,你能够应用child_process模块,像这么导入它:

复制代码 代码如下:

var child_process = require(‘child_process')

下一场能够用模块内的exec函数来进行外界命令:

复制代码 代码如下:

var exec = child_process.exec;

exec(command,callback);

exec的率先个参数是你计划奉行的shell命令字符串,第2个参数是叁个回调函数。那么些回调函数将会在exec奉行完外界命令可能有不当发生时被调用。回调函数有四个参数:error,stdout,stderr,看上边的事例:

复制代码 代码如下:

exec(‘ls',function(err,stdout,stderr){

         //译者注:借使选取windows,可改为windows命令,比方dir,后边不再赘言

});

比方有荒唐发生,第叁个参数将会是五个Error类的实例,要是第四个参数不分包错误,那么第2个参数stdout将会含有命令的行业内部输出。最终三个参数包涵命令相关的一无所长输出。

列表8-1 体现了三个头昏眼花些的施行外部命令的例子

LISTING 8-1:实施外界命令(源码:chapter8/01_external_command.js)

复制代码 代码如下:

//导入child_process模块的exec函数
var exec = require(‘child_process').exec;
//调用“cat *.js | wc -l”命令
exec(‘cat *.js | wc –l ‘, function(err, stdout, stderr ){  //第四行
         //命令退出可能调用退步
         if( err ){
              //运营外界进程受挫
              console.log(‘child_process 退出,错误码是:',err.code);
              return;
         }
}

第四行,我们把“cat *.js | wc -l”作为第几个参数字传送递给exec,你也得以品味任何其余命令,只要你在shell里采纳过的下令都能够。

下一场将三个回调函数作为第三个参数,它将会在错误产生也许子进度终结的时候被调用。

还足以在回调函数此前传递第多少个可选参数,它含有部分公司署选项,比方:

复制代码 代码如下:

var exec = require(‘child_process').exec;       

var options ={
         timeout: 1000,
         killSignal: ‘SIGKILL'
     };

exec(‘cat *.js | wc –l ‘, options, function(err,stdout,stderr){
         //…
});

能够行使的参数有:

1.cwd —— 当前目录,能够钦命当前职业目录。
2.encoding —— 子进程输出内容的编码格式,默许值是”utf8”,也正是UTF-8编码。假设实进度的出口不是utf8,你能够用这么些参数来安装,协理的编码格式有:

复制代码 代码如下:

ascii
utf8
ucs2
base64

若果你想通晓Node帮衬的那一个编码格式的更加多音信,请参见第4章“使用Buffer管理,编码,解码二进制数据”。

1.timeout —— 以微秒为单位的下令奉行超时时间,暗中认可是0,即无界定,一向等到子进度甘休。
2.maxBuffer —— 内定stdout流和stderr流允许输出的最大字节数,假如到达最大值,子进度会被杀掉。私下认可值是200*1024。
3.killSignal —— 当超时也许输出缓存到达最大值时发送给子过程的终结能量信号。暗许值是“SIGTERM”,它将给子进度发送贰个扫尾功率信号。平日都会采纳这种平稳的不二等秘书诀来收场进程。当用SIGTERM功率信号时,进程接收到现在还足以开展处理依然重写频限信号管理器的私下认可行为。即便指标经过要求,你可以同临时间向他传递另外的复信号(举例SIGUS奔驰G级1)。你也能够挑选发送多少个SIGKILL复信号,它会被操作系统处理并要挟立时结束子进度,那样的话,子进度的别的清理操作都不会被推行。

即使你想更进一竿的调节进程的竣事,能够应用child_process.spawn命令,后边会介绍。

1.evn —— 内定传递给子进度的情形变量,暗中同意是null,也便是说子进度会继续在它被创立从前的富有父进程的情况变量。

瞩目:使用killSignal选项,你能够以字符串的情势向目的经过发送信号。在Node里时域信号以字符串的花样存在,上面是UNIX实信号和呼应暗许操作的列表:

图片 1

图片 2

图片 3

您可能想为子进程提供一组可扩充的父级情状变量。假如直接去修改process.env对象,你会变动Node进度内部存款和储蓄器有模块的情况变量,那样会惹众多烦劳。替代方案是,创立多个新目的,复制process.env里的有着参数,见例子8-2:

LISTING 8-2:使用参数化的情形变量来实施命令(源码:chapter8/02_env_vars_augment.js)

复制代码 代码如下:

var env = process.env,
    varName,
    envCopy = {},
    exec = require(‘child_prcess').exec;
//将process.env复制到envCopy
for( vaName in ev){
    envCopy[varName] = env[varName];
}

//设置有个别自定义变量
envCopy[‘CUSTOM ENV VAR1'] = ‘some value';
envCopy[‘CUSTOM ENV VAR2'] = ‘some other value';

//使用process.env和自定义变量来施行命令
exec(‘ls –la',{env: envCopy}, function(err,stdout,stderr){
    if(err){ throw err; }
    console.log(‘stdout:', stdout);
    console.log(‘stderr:',stderr);
}

上面例子,创立了一个用来保存情形变量的envCopy变量,它首先从process.env这里复制Node进度的情况变量,然后又增加或交换了部分急需修改的情况变量,最后把envCopy作为意况变量参数字传送递给exec函数并施行外界命令。

铭记,意况变量是经过操作系统在进度之间传递的,全体项目标条件变量值都以以字符串的款式达到子进度的。举例,假如父进度将数字123当做二个情况变量,子进度将会以字符串的样式接受“123”。

下边包车型大巴事例,将要同一个目录里创设2个Node脚本:parent.js和child.js,第一个本子将会调用第二个,上面大家来创建那七个公文:

LISTING 8-3: 父进度设置情状变量(chapter8/03_environment_number_parent.js)

复制代码 代码如下:

var exec = require('child_process').exec;

exec('node child.js', {env: {number: 123}}, function(err, stdout, stderr) {

if (err) { throw err; }

    console.log('stdout:n', stdout);

    console.log('stderr:n', stderr);

});

把这段代码保存到parent.js,上面是子进程的源码,把它们保存到child.js(见例8-4)

例 8-4: 子进度解析景况变量(chapter8/04_environment_number_child.js)

复制代码 代码如下:

var   number = process.env.number;

console.log(typeof(number)); // → "string"

number = parseInt(number, 10);

console.log(typeof(number)); // → "number"

当你把那么些文件保留为child.js后,就足以在那些目录下运营上边包车型客车通令:

复制代码 代码如下:

$ node parent.js

将拜见到如下的出口:

复制代码 代码如下:

sdtou:

string

number

stderr:

能够见见,就算父进度传递了贰个数字型的情形变量,不过子进度却以字符串格局接受它(参见输出的第二行),在第三行你把那个字符串解析成了一个数字。

生成子进度

如您所见,能够使用child_process.exec()函数来运转外界进程,并在经过甘休的时候调用你的回调函数,这样用起来很简短,可是也会有一对宿疾:

1.除了行任务令行参数和景况变量,使用exec()不能和子进度通信
2.子进度的输出是被缓存的,因而你无法流化它,它也许会耗尽内部存款和储蓄器

侥幸的是,Node的child_process模块允许更细粒度的调节子进程的起步,甘休,及任何正规操作。你能够在应用程序里运行三个新的子进程,Node提供贰个双向的通信通道,能够让父进度和子进度并行收发字符串数据。父进度还是能够稍微针对子进度的田管操作,给子进程发送时域信号,以及强制关闭子进度。

创立子进度

你可以动用child_process.spawn函数来创制三个新的子进度,见例8-5:

例 8-5: 生成子进度。 (chapter8/05_spawning_child.js)

复制代码 代码如下:

// 导入child_process模块的spawn函数

var spawn = require('child_process').spawn;

// 生成用来试行 "tail -f /var/log/system.log"命令的子进度

var child = spawn('tail', ['-f', '/var/log/system.log']);

地方代码生成了一个用来实践tail命令的子进度,并将“-f”和“/bar/log/system.log”作为参数。tail命令将会监督检查/var/log/system.og文件(要是存在的话),然后将具备追加的新数据输出到stdout标准输出流。spawn函数再次回到一个ChildProcess对象,它是三个指针对象,封装了实在进程的拜见接口。那些例子里大家把这些新的汇报符赋值给贰个叫作child的变量。

监听来自子进度的数量

其它带有stdout属性的子进度句柄,都会将子进度的正经输出stdout作为一个流对象,你能够在这一个流对象上绑定data事件,那样每当有数据块可用时,就能够调用对应的回调函数,见上面包车型地铁事例:

复制代码 代码如下:

 //将子进度的出口打字与印刷到调控台

child.stdout.on(‘data',function(data){

         console.log(‘tail output: ‘ + data);

});

每当子进度将数据输出到正式输出stdout时,父进程就能够得到通告并把多少打字与印刷到调控台。

除了正式输出,进程还只怕有另外三个暗中同意输出流:标准错误流,经常用那几个流来输出错误新闻。

在那一个例子里,借使/var/log/system.log文件不真实,tail进度将会输出周围上边包车型客车音信:“/var/log/system.log:No such file or directory”,通过监听stderr流,父进度会在这种不当产生时得到照望。

父进程能够如此监听规范错误流:

复制代码 代码如下:

child.stderr.on('data', function(data) {

    console.log('tail error output:', data);

});

 stderr属性和stdout同样,也是只读流,每当子进度往专门的工作错误流里输出数据时,父进度就能够获得照拂,并出口数据。

发送数据到子进度

除外从子进度的出口流里接收数据,父进度还足以因此childPoces.stdin属性往子进度的正式输入里写入数据,以此来往子进程发送数据。

子进度能够经过process.stdin只读流来监听规范输入的多少,不过注意你首先必得得回复(resume)标准输入流,因为它暗中认可处于停顿(paused)状态。

例8-6将会成立贰个饱含如下效果的顺序:

1.+1 施用:三个简练的应用程序,能够从标准输入接收整型,然后相加,再把相加以后的结果输出到标准输出流。这几个利用作为三个简约的乘除服务, 把Node进度模拟成贰个能够进行一定专门的学问的表面服务。

2.测量试验+1运用的客商端,发送随机整型,然后输出结果。用来演示Node进程怎么样生成三个子进度然后让它施行一定的天职。

用上边例8-6的代码成立贰个名称叫plus_one.js的文件:

例 8-6: +1 应用程序(chapter8/06_plus_one.js)

复制代码 代码如下:

// 苏醒暗中认可是暂停状态的标准输入流
process.stdin.resume();
process.stdin.on('data', function(data) {
    var number;
    try {
        // 将输入数据分析为整型
        number = parseInt(data.toString(), 10);
        // +1
        number += 1;
        // 输出结果
        process.stdout.write(number + "n");
    } catch(err) {
        process.stderr.write(err.message + "n");
    }
});

地点代码里,大家静观其变来自stdin规范输入流的数额,每当有数据可用,就借使它是个整型并把它深入分析到三个整型变量里,然后加1,并把结果输出到正规输出流。

能够因而上面发号施令来运作那些程序:

复制代码 代码如下:

    $ node plus_one.js

运转后前后相继就起来等候输入,假诺你输入二个整数然后按回车,就拜访到三个被加1未来的数字被显示到荧屏上。

可以透过按Ctrl-C来退出程序。

多个测验顾客端

当今您要创立多少个Node进度来使用前边的“+1采纳”提供的一个钱打二17个结服务。

先是成立多少个名字为plus_one_test.js的文书,内容见例8-7:

例 8-7: 测试+1应用(chapter8/07_plus_one_test.js)

复制代码 代码如下:

var spawn = require('child_process').spawn;
// 生成三个子经过来进行+1施用
var child = spawn('node', ['plus_one.js']);
// 每一秒调用三遍函数
setInterval(function() {
    // Create a random number smaller than 10.000
    var number = Math.floor(Math.random() * 10000);
    // Send that number to the child process:
    child.stdin.write(number + "n");
    // Get the response from the child process and print it:
    child.stdout.once('data', function(data) {
        console.log('child replied to ' + number + ' with: ' + data);
    });
}, 1000);
child.stderr.on('data', function(data) {
    process.stdout.write(data);
});

 从第一行到第四行运行了四个用来运营“+1利用”的子进度,然后接纳setInterval函数每分钟实行一遍下列操作:

1..新建多少个紧跟于一千0的随便数
2.将以此数字作为字符串传递给子进度
3.等待子进度恢复生机贰个字符串
4.因为您想每一次只收取1个数字的企图结果,因而供给运用child.stdout.once实际不是child.stdout.on。如若选取了前面一个,会每隔1秒注册八个data事件的回调函数,每一种被注册的回调函数都会在子进程的stdout接收到数量时被推行,那样您会发掘同二个划算结果会被输出数10次,这种表现明确是错的。

在子进程退出时吸收通知

当子进度退出时,exit事件会被触发。例8-8显得了怎么监听它:

例 8-8: 监听子进度的退出事件 (chapter8/09_listen_child_exit.js)

复制代码 代码如下:

var spawn = require('child_process').spawn;
// 生成子进度来试行 "ls -la"命令
var child = spawn('ls', ['-la']);
child.stdout.on('data', function(data) {
    console.log('data from child: ' + data);
});

// 当子进程退出:
<strong>child.on('exit', function(code) {
    console.log('child process terminated with code ' + code);
});</strong>

最后几行加黑的代码,父进度使用子进程的exit事件来监听它的淡出事件,当事件发生时,调节台彰显相应的输出。子进程的退出码会被看作第三个参数字传送递给回调函数。某个程序选拔二个非0的脱离码来表示某种退步状态。比方,要是您品味奉行命令“ls –al click filename.txt”,但是当前目录未有那几个文件,你就可以获得几个值为1的退出码,见例8-9:

例8-9:得到子进度的退出码 (chapter8/10_child_exit_code.js)

复制代码 代码如下:

var spawn = require('child_process').spawn;
// 生成子进度,推行"ls does_not_exist.txt" 命令
var child = spawn('ls', ['does_not_exist.txt']);
// 当子进度退出
child.on('exit', function(code) {
    console.log('child process terminated with code ' + code);
});

本条例子里,exit事件触发了回调函数,并把子进度的退出码作为第二个参数字传送递给它。假如实进度是被功率信号杀死而致使的窘迫退出,那么相应的非确定性信号代码会被看成第一个参数字传送递给回调函数,如例8-10:

LISTING 8-10: 获得子进度的退出功率信号(chapter8/11_child_exit_signal.js)

复制代码 代码如下:

var spawn = require('child_process').spawn;
// 生成子进度,运营"sleep 10"命令
var child = spawn('sleep', ['10']);
setTimeout(function() {
    child.kill();
}, 1000);
child.on('exit', function(code, signal) {
    if (code) {
        console.log('child process terminated with code ' + code);
    } else if (signal) {
        console.log('child process terminated because of signal ' + signal);
    }
});

本条例子里,运营贰个子进度来进行sleep 10秒的操作,可是还没到10秒就发送了三个SIGKILL时域信号给子进度,那将会促成如下的输出:

复制代码 代码如下:

child process terminated because of signal SIGTERM

出殡非时域信号并杀死进度

在这一部分,你将学习怎样运用功率信号来管理子进度。时域信号是父进度用来跟子进度通讯,以至杀死子进程的一种轻便方法。

昨今不一致的非确定性信号代码代表分化的含义,有广大时域信号,当中最遍布的片段是用来杀死进度的。要是一个进度接收到一个它不晓得怎么样管理的能量信号,程序就能够被非凡中断。有个别非确定性信号会被子进程处理,而有一点点只好由操作系统管理。

相似景色下,你能够运用child.kill方法来向子进程发送二个确定性信号,默许发送SIGTERM确定性信号:

复制代码 代码如下:

var spawn = require('child_process').spawn;
var child = spawn('sleep', ['10']);
setTimeout(function() {
    child.kill();
}, 1000);

还足以因此传播三个标志数字信号的字符串作为kill方法的独一参数,来发送某些特定的非能量信号:

复制代码 代码如下:

child.kill(‘SIGUSR2');

亟待专心的是,固然这些主意的名字叫kill,不过发送的时域信号并不一定会杀死子进度。如若实进度处理了时限信号,默许的实信号行为就能够被覆盖。用Node写的子进度能够像上边那样重写非确定性信号管理器的概念:

复制代码 代码如下:

process.on('SIGUSR2', function() {
    console.log('Got   a SIGUSR2 signal');
});

今天,你定义了SIGUSMurano2的能量信号管理器,当你的进程再抽出SIGUSCR-V2时域信号的时候就不会被杀掉,而是输出“Got a SIGUSLacrosse2 signal”那句话。使用这种体制,你能够安排一种简易的艺术来跟子进度交换以至命令它。即使不像使用正规输入功能那么足够,不过那格局要简明相当多。

小结

这一章,学习了应用child_process.exec方法来进行外部命令,这种形式得以不应用命令行参数,而是通过定义境遇变量的艺术把参数字传送递给子进程。

还学习了经过调用child_process.spawn方法生成子进程的点子来调用外界命令,这种措施你可以行使输入流,输出流来跟子进度通讯,也许采取复信号来跟子进度通信以及杀死进度。

子进程模块:childProcess = require("child_process");

NodeJS子进度简要介绍 NodeJS子进度提供了与系统互相的主要性接口,其重要API有: 标准输入、标准输出及业内错误输出的接口。

别的一种需求使用子进度的意况是,当您想大概地施行一个外界命令,并让Node获取命令的归来值时。比方,你能够实行一个UNIX命令、脚本可能别的那多少个无法在Node里直接执行的吩咐。

nodejs开垦指南里面创制今日头条例子中,在建设构造注册账户的经过中报错

哪怕setting.js,自个儿写的三个停放数据库配置文件的js。那不是旁人写的模块是温馨创制的seting.js文件,里面包车型大巴剧情是三个json
moudule.exports = {
cookieSecret:'microblogbyvoid',
db:'microblog',
host:'localhost'

请仿效《node.js开荒指南》的P109页。
仿照效法资料:《node.js开荒指南》  

1、var spawn = childProcess.spawn(command, [,args],[,options]])

NodeJS子进程简单介绍

本章将向你出示怎么着推行外部命令,创制,并和子进度通讯,以及终结子进度。入眼是令你询问什么在Node进程外产生一雨后玉兰片职务。

nodejs 不用文件怎创制流?

node.js的api里面包车型地铁stream.Readable和stream.Writable都是空虚的,你得看您实际要求干什么,再产生你谐和的Readable恐怕Writable。譬喻fs里面createReadStream再次回到的是fs里面继续自Readable的ReadStream,net里面包车型客车Socket是持续自stream.Duplex的可以读也足以写的stream。  

Node被规划用来飞速的拍卖I/O操作,可是你应有知道,有些项目标主次并不符合这种形式。举个例子...

     command: 只执行shell指令

NodeJS 子进度提供了与系统相互的首要接口,其珍视 API 有:

施行外界命令

     args: 实行参数列表

专门的学问输入、标准输出及专门的事业错误输出的接口
child.stdin 得到标准输入
child.stdout 得到标准输出
child.stderr 拿到规范错误输出
获取子进度的PID:child.pid
提供生成子进度的首要措施:child_process.spawn(cmd, args=[], [options])
提供第一手实行系统命令的首要格局:child_process.exec(cmd, [options], callback)
提供杀死进度的诀窍:child.kill(signal='SIGTERM')

当你要求施行三个外界shell命令或可实行文件时,你能够利用child_process模块,像这样导入它:

     options: 情况变量对象

实例一:利用子进度取得系统内部存款和储蓄器使用景况
将以下代码保存为 free.js:

复制代码 代码如下:


复制代码 代码如下:

var child_process = require(‘child_process')

其间景况变量对象有八个性子:

var spawn = require('child_process').spawn,
free = spawn('free', ['-m']);

下一场能够用模块内的exec函数来奉行外界命令:

     env: 情形变量键值对

// 捕获专门的学业输出并将其打字与印刷到调控台
free.stdout.on('data', function (data) {
console.log('标准输出:n' + data);
});

复制代码 代码如下:

     cwd:子进度前段时间的专门的学问目录

// 捕获正式错误输出并将其打字与印刷到控制台
free.stderr.on('data', function (data) {
console.log('标准错误输出:n' + data);
});

var exec = child_process.exec;

     stdio: 子进度的stdio配置

// 注册子进度关闭事件
free.on('exit', function (code, signal) {
console.log('子进程已退出,代码:' + code);
});

exec(command,callback);

     customFds: 作为子进程stdio使用的文本标示符

施行代码后的结果:

exec的首先个参数是您筹划实践的shell命令字符串,第一个参数是二个回调函数。那些回调函数将会在exec施行完外界命令也许有错误发生时被调用。回调函数有多少个参数:error,stdout,stderr,看下边包车型大巴例证:

     uid: 客户进度ID

$ node free.js
正规输出:
total used free shared buffers cached
Mem: 3949 1974 1974 0 135 959
-/+ buffers/cache: 879 3070
Swap: 3905 0 3905

复制代码 代码如下:

     gid: 进程组ID

子进程已脱离,代码:0
以上输出非常与在命令行实践:free -m 命令。

exec(‘ls',function(err,stdout,stderr){

     detached: 进程组主要调控制

透过那几个简单的事例大家早已对子进程的选用具备驾驭,上面再来一个示例,用于演示exec 的施用形式。

         //译者注:借使使用windows,可改为windows命令,例如dir,前边不再赘述

//windows系统下的吩咐;

var  spawn=require('child_process').spawn,

free=spawn('cat',['a.txt'],{cwd:'./a'});

// 捕获专业输出并将其打字与印刷到调整台

free.stdout.on('data',function(data){console.log('标准输出:'+data);});

// 捕获职业错误输出并将其打字与印刷到调节台

free.stderr.on('data',function(data){console.log('规范错误输出:'+data);})

;// 注册子进度关闭事件

free.on('exit',function(code,signal){console.log('子进程已退出,代码:'+code);});

实例二:利用子进程总括系统登入次数
将上边代码保存为 last.js

});

2、childProcess.exec(command, function(err, stdout, stderr) {  })

复制代码 代码如下:

如若有荒唐发生,第二个参数将会是二个Error类的实例,假使第二个参数不含有错误,那么第二个参数stdout将会蕴藏命令的正式输出。最终一个参数满含命令相关的荒唐输出。

其中command是shell命令,相当于spawn的command+args

var exec = require('child_process').exec,
last = exec('last | wc -l');

列表8-1 突显了多个长短不一些的实行外界命令的例子

var childProcess = require("child_process");

childProcess.exec('node linyanxiang.js', function(err, stdout, stderr) {

        console.log(stdout)

})

last.stdout.on('data', function (data) {
console.log('标准输出:' + data);
});

LISTING 8-1:实行外界命令(源码:chapter8/01_external_command.js)

3.childProcess.execFile(command, [args], [options],function(error, stdout, stderr){});

last.on('exit', function (code) {
console.log('子进程已关闭,代码:' + code);
});

复制代码 代码如下:

是spawn与exec综合

奉行代码:

//导入child_process模块的exec函数
var exec = require(‘child_process').exec;
//调用“cat *.js | wc -l”命令
exec(‘cat *.js | wc –l ‘, function(err, stdout, stderr ){  //第四行
         //命令退出大概调用败北
         if( err ){
              //运转外部进度受挫
              console.log(‘child_process 退出,错误码是:',err.code);
              return;
         }
}

command,args,options参数的含义与spawn的含义同样,回调函数的用法与exec同样。

$ node last.js
行业内部输出:203

第四行,我们把“cat *.js | wc -l”作为第一个参数传递给exec,你也能够品味任何别的命令,只要你在shell里应用过的指令都足以。

4.fork 父进度与子进度之间成立通讯

子进度已关门,代码:0
其与间接在命令行输入:last | wc -l 的结果是平等的。

下一场将二个回调函数作为第三个参数,它将会在错误发生或许子进程终结的时候被调用。

//父进程

var childProcess = require('child_process');

var subFork = childProcess.fork('sub.js');

subFork.on('message', function(m) {

       console.log("message" + m);

})

subFork.send({'hell0': 'world'})

//子进程

process.on('message', function(m) {

      console.log(m)

})

process.send({name:'dayday'})

你或然感兴趣的稿子:

  • Node.js中child_process完成多进度
  • 详解从Node.js的child_process模块来上学老爹和儿子进度之间的通讯
  • 详解node child_process模块学习笔记
  • node的process以及child_process模块学习笔记
  • Node.js中的child_process模块详解

还是能够在回调函数在此以前传递第三个可选参数,它蕴涵部分配置选项,比如:

复制代码 代码如下:

var exec = require(‘child_process').exec;       

var options ={
         timeout: 1000,
         killSignal: ‘SIGKILL'
     };

exec(‘cat *.js | wc –l ‘, options, function(err,stdout,stderr){
         //…
});

可以使用的参数有:

1.cwd —— 当前目录,能够内定当前专业目录。
2.encoding —— 子进度输出内容的编码格式,暗中认可值是”utf8”,也正是UTF-8编码。如若实进程的输出不是utf8,你能够用这几个参数来设置,帮忙的编码格式有:

复制代码 代码如下:

ascii
utf8
ucs2
base64

设若你想领会Node帮忙的这么些编码格式的越来越多音讯,请参见第4章“利用Buffer管理,编码,解码二进制数据”。

1.timeout —— 以飞秒为单位的指令实行超时时间,暗中同意是0,即无界定,一向等到子进程截至。
2.maxBuffer —— 钦命stdout流和stderr流允许输出的最大字节数,借使达到最大值,子进度会被杀死。暗中同意值是200*1024。
3.killSignal —— 当超时恐怕输出缓存达到最大值时发送给子进度的了断频域信号。私下认可值是“SIGTERM”,它将给子进度发送三个得了实信号。经常都会利用这种平稳的格局来终结进度。当用SIGTERM非时域信号时,进度接收到今后还是能开展管理依然重写数字信号管理器的暗中同意行为。借使指标经过须要,你能够何况向他传递其余的能量信号(比方SIGUSTiguan1)。你也得以选用发送一个SIGKILL能量信号,它会被操作系统管理并威胁马上结束子进度,那样的话,子进度的别的清理操作都不会被推行。

假定你想更进一竿的垄断进程的扫尾,能够行使child_process.spawn命令,前面会介绍。

1.evn —— 钦点传递给子进度的情形变量,私下认可是null,也正是说子进度会继续在它被创设以前的有着父进度的情况变量。

留心:使用killSignal选项,你能够以字符串的款式向目的经过发送非确定性信号。在Node里实信号以字符串的款型存在,下边是UNIX能量信号和相应暗中认可操作的列表:

图片 4

图片 5

图片 6

您大概想为子过程提供一组可扩充的父级景况变量。假设一向去修改process.env对象,你会转移Node进度内具有模块的意况变量,那样会惹众多劳神。代替方案是,创立叁个新目的,复制process.env里的保有参数,见例子8-2:

LISTING 8-2:使用参数化的意况变量来实施命令(源码:chapter8/02_env_vars_augment.js)

复制代码 代码如下:

var env = process.env,
    varName,
    envCopy = {},
    exec = require(‘child_prcess').exec;
//将process.env复制到envCopy
for( vaName in ev){
    envCopy[varName] = env[varName];
}

//设置有些自定义变量
envCopy[‘CUSTOM ENV VAR1'] = ‘some value';
envCopy[‘CUSTOM ENV VAR2'] = ‘some other value';

//使用process.env和自定义变量来奉行命令
exec(‘ls –la',{env: envCopy}, function(err,stdout,stderr){
    if(err){ throw err; }
    console.log(‘stdout:', stdout);
    console.log(‘stderr:',stderr);
}

上边例子,创立了叁个用以保存境况变量的envCopy变量,它首先从process.env这里复制Node进度的景况变量,然后又增加或沟通了有的索要修改的景况变量,最终把envCopy作为境遇变量参数字传送递给exec函数并施行外部命令。

切记,情形变量是经过操作系统在进度之间传递的,全部品种的情形变量值都以以字符串的样式达到子进度的。比方,假诺父进度将数字123看作一个情状变量,子进程将会以字符串的花样接受“123”。

上面包车型地铁事例,将要同一个目录里营造2个Node脚本:parent.js和child.js,第八个本子将会调用第一个,上边大家来创建那多少个文件:

LISTING 8-3: 父进程设置情状变量(chapter8/03_environment_number_parent.js)

复制代码 代码如下:

var exec = require('child_process').exec;

exec('node child.js', {env: {number: 123}}, function(err, stdout, stderr) {

if (err) { throw err; }

    console.log('stdout:n', stdout);

    console.log('stderr:n', stderr);

});

把这段代码保存到parent.js,下边是子进度的源码,把它们保存到child.js(见例8-4)

例 8-4: 子进度剖析情状变量(chapter8/04_environment_number_child.js)

复制代码 代码如下:

var   number = process.env.number;

console.log(typeof(number)); // → "string"

number = parseInt(number, 10);

console.log(typeof(number)); // → "number"

当您把这几个文件保留为child.js后,就可以在那么些目录下运作上边的一声令下:

复制代码 代码如下:

$ node parent.js

将会看到如下的出口:

复制代码 代码如下:

sdtou:

string

number

stderr:

能够看出,纵然父进度传递了贰个数字型的境况变量,可是子进度却以字符串格局选择它(参见输出的第二行),在第三行你把这么些字符串剖析成了贰个数字。

生成子进度

如你所见,能够行使child_process.exec()函数来运转外界进程,并在经过结束的时候调用你的回调函数,那样用起来很简单,可是也许有局地弱点:

1.除了行职分令行参数和情状变量,使用exec()不可能和子进程通信
2.子进度的出口是被缓存的,由此你不可能流化它,它或者会耗尽内部存款和储蓄器

有幸的是,Node的child_process模块允许越来越细粒度的调整子进程的运维,停止,及别的正规操作。你能够在应用程序里运营叁个新的子进程,Node提供二个双向的通讯通道,能够让父进度和子进度并行收发字符串数据。父进度仍是可以稍微针对子进度的保管操作,给子进度发送时限信号,以及强制关闭子进度。

成立子进度

您能够运用child_process.spawn函数来创立二个新的子进程,见例8-5:

例 8-5: 生成子进度。 (chapter8/05_spawning_child.js)

复制代码 代码如下:

// 导入child_process模块的spawn函数

var spawn = require('child_process').spawn;

// 生成用来实施 "tail -f /var/log/system.log"命令的子进度

var child = spawn('tail', ['-f', '/var/log/system.log']);

地方代码生成了四个用来施行tail命令的子进程,并将“-f”和“/bar/log/system.log”作为参数。tail命令将会监督检查/var/log/system.og文件(借使存在的话),然后将富有追加的新数据输出到stdout标准输出流。spawn函数再次回到四个ChildProcess对象,它是多少个指针对象,封装了真实进程的会见接口。这几个例子里我们把这几个新的陈说符赋值给七个叫做child的变量。

监听来自子进度的多寡

其他带有stdout属性的子进度句柄,都会将子进度的专业输出stdout作为一个流对象,你可以在那个流对象上绑定data事件,那样每当有数据块可用时,就能调用对应的回调函数,见下边包车型的士事例:

复制代码 代码如下:

 //将子进度的出口打字与印刷到调控台

child.stdout.on(‘data',function(data){

         console.log(‘tail output: ‘ + data);

});

每当子进程将数据输出到标准输出stdout时,父进度就能够拿走照望并把数量打字与印刷到调整台。

除外专门的学问输出,进度还大概有别的二个默许输出流:规范错误流,平日用这一个流来输出错误信息。

在那几个例子里,要是/var/log/system.log文件不设有,tail进度将会输出周边下边包车型地铁音讯:“/var/log/system.log:No such file or directory”,通过监听stderr流,父进度会在这种不当发生时获得布告。

父进程能够这么监听标准错误流:

复制代码 代码如下:

child.stderr.on('data', function(data) {

    console.log('tail error output:', data);

});

 stderr属性和stdout同样,也是只读流,每当子进程往专门的学业错误流里输出数据时,父进度就能够拿走照料,并出口数据。

发送数据到子进度

除去从子进度的输出流里接收数据,父进度还足以经过childPoces.stdin属性往子进程的标准输入里写入数据,以此来往子进度发送数据。

子进度能够透过process.stdin只读流来监听标准输入的数目,可是注意你首先必需得回复(resume)标准输入流,因为它默许处于停顿(paused)状态。

例8-6将会创建二个包蕴如下效果的顺序:

1.+1 施用:一个简约的应用程序,能够从标准输入接收整型,然后相加,再把相加以往的结果输出到职业输出流。那一个利用作为一个简便的计算服务, 把Node进度模拟成二个得以实行一定工作的表面服务。

2.测量试验+1施用的客商端,发送随机整型,然后输出结果。用来演示Node进度怎么样生成叁个子进程然后让它实践一定的天职。

用上面例8-6的代码成立贰个名称为plus_one.js的文件:

例 8-6: +1 应用程序(chapter8/06_plus_one.js)

复制代码 代码如下:

// 苏醒默许是搁浅状态的正儿八经输入流
process.stdin.resume();
process.stdin.on('data', function(data) {
    var number;
    try {
        // 将输入数据分析为整型
        number = parseInt(data.toString(), 10);
        // +1
        number += 1;
        // 输出结果
        process.stdout.write(number + "n");
    } catch(err) {
        process.stderr.write(err.message + "n");
    }
});

上边代码里,我们静观其变来自stdin标准输入流的数据,每当有数据可用,就如果它是个整型并把它深入分析到多少个整型变量里,然后加1,并把结果输出到标准输出流。

能够经过下边发号施令来运作这一个程序:

复制代码 代码如下:

    $ node plus_one.js

运转后前后相继就起来等候输入,借令你输入贰个整数然后按回车,就探访到多个被加1以往的数字被展现到显示器上。

可以通过按Ctrl-C来退出程序。

一个测量试验顾客端

当今您要成立二个Node进程来行使后面包车型地铁“+1采取”提供的估量服务。

率先创造二个名称为plus_one_test.js的公文,内容见例8-7:

例 8-7: 测试+1应用(chapter8/07_plus_one_test.js)

复制代码 代码如下:

var spawn = require('child_process').spawn;
// 生成四个子进度来实施+1施用
var child = spawn('node', ['plus_one.js']);
// 每一秒调用三回函数
setInterval(function() {
    // Create a random number smaller than 10.000
    var number = Math.floor(Math.random() * 10000);
    // Send that number to the child process:
    child.stdin.write(number + "n");
    // Get the response from the child process and print it:
    child.stdout.once('data', function(data) {
        console.log('child replied to ' + number + ' with: ' + data);
    });
}, 1000);
child.stderr.on('data', function(data) {
    process.stdout.write(data);
});

 从第一行到第四行运营了叁个用来运作“+1利用”的子进程,然后接纳setInterval函数每秒钟推行二回下列操作:

1..新建二个稍差于10000的私下数
2.将以此数字作为字符串传递给子进度
3.等待子进度恢复一个字符串
4.因为你想每回只抽取1个数字的测算结果,由此须求运用child.stdout.once实际不是child.stdout.on。要是运用了前面一个,会每隔1秒注册贰个data事件的回调函数,每种被登记的回调函数都会在子进度的stdout接收到数码时被实行,那样您会发掘同三个企图结果会被输出多次,这种行为肯定是错的。

在子进度退出时吸取公告

当子进度退出时,exit事件会被触发。例8-8展现了什么样监听它:

例 8-8: 监听子进程的淡出事件 (chapter8/09_listen_child_exit.js)

复制代码 代码如下:

var spawn = require('child_process').spawn;
// 生成子过程来实施 "ls -la"命令
var child = spawn('ls', ['-la']);
child.stdout.on('data', function(data) {
    console.log('data from child: ' + data);
});

// 当子进度退出:
<strong>child.on('exit', function(code) {
    console.log('child process terminated with code ' + code);
});</strong>

末尾几行加黑的代码,父进度使用子进度的exit事件来监听它的脱离事件,当事件发生时,调节台突显相应的输出。子进程的退出码会被看成第三个参数字传送递给回调函数。有个别程序行使多个非0的脱离码来表示某种败北状态。譬如,就算您品味执行命令“ls –al click filename.txt”,可是当前目录没有那个文件,你就能够拿走叁个值为1的退出码,见例8-9:

例8-9:得到子进度的淡出码 (chapter8/10_child_exit_code.js)

复制代码 代码如下:

var spawn = require('child_process').spawn;
// 生成子进度,推行"ls does_not_exist.txt" 命令
var child = spawn('ls', ['does_not_exist.txt']);
// 当子进度退出
child.on('exit', function(code) {
    console.log('child process terminated with code ' + code);
});

以那件事例里,exit事件触发了回调函数,并把子进度的退出码作为第三个参数传递给它。如果实进度是被频限信号杀死而导致的难堪退出,那么相应的非非确定性信号代码会被当作第四个参数字传送递给回调函数,如例8-10:

LISTING 8-10: 获得子进度的淡出时域信号(chapter8/11_child_exit_signal.js)

复制代码 代码如下:

var spawn = require('child_process').spawn;
// 生成子进度,运转"sleep 10"命令
var child = spawn('sleep', ['10']);
setTimeout(function() {
    child.kill();
}, 1000);
child.on('exit', function(code, signal) {
    if (code) {
        console.log('child process terminated with code ' + code);
    } else if (signal) {
        console.log('child process terminated because of signal ' + signal);
    }
});

以这件事例里,运营三个子历程来举办sleep 10秒的操作,可是还没到10秒就发送了一个SIGKILL时域信号给子进度,那将会招致如下的出口:

复制代码 代码如下:

child process terminated because of signal SIGTERM

发送随机信号并杀死进度

在那部分,你将学习怎么使用非确定性信号来管理子进程。确定性信号是父进度用来跟子进度通讯,以至杀死子进程的一种简易方法。

不等的连续信号代码代表分裂的意思,有繁多时限信号,在那之中最广大的有个别是用来杀死进度的。假诺多个经过接收到四个它不亮堂什么管理的复信号,程序就能够被非常中断。有些信号会被子进程管理,而略带只可以由操作系统管理。

貌似意况下,你能够利用child.kill方法来向子进程发送贰个复信号,默许发送SIGTERM时限信号:

复制代码 代码如下:

var spawn = require('child_process').spawn;
var child = spawn('sleep', ['10']);
setTimeout(function() {
    child.kill();
}, 1000);

仍是能够通过传播叁个标记功率信号的字符串作为kill方法的独一无二参数,来发送某些特定的时域信号:

复制代码 代码如下:

child.kill(‘SIGUSR2');

亟需注意的是,即使这些方法的名字叫kill,然则发送的非确定性信号并不一定会杀死子进度。假若实进度管理了实信号,暗中认可的功率信号行为就能被遮住。用Node写的子进度能够像上面那样重写时限信号处理器的定义:

复制代码 代码如下:

process.on('SIGUSR2', function() {
    console.log('Got   a SIGUSR2 signal');
});

于今,你定义了SIGUSENCORE2的非数字信号管理器,当你的长河再接过SIGUS昂Cora2非非确定性信号的时候就不会被杀掉,而是输出“Got a SIGUSTucson2 signal”那句话。使用这种体制,你可以设计一种简易的格局来跟子进度交流以至命令它。即使不像使用标准输入作用那么足够,然则那措施要轻易非常多。

小结

这一章,学习了运用child_process.exec方法来实践外部命令,这种办法得以不使用命令行参数,而是通过定义情形变量的方法把参数字传送递给子进度。

还学习了经过调用child_process.spawn方法生成子进度的章程来调用外界命令,这种方法你能够利用输入流,输出流来跟子进度通讯,只怕应用功率信号来跟子进度通讯以及杀死进程。

你或者感兴趣的篇章:

  • Nodejs进度管理模块forever详解
  • Nodejs极简入门教程(三):进度
  • node.js使用cluster完结多进度
  • 谨防Node.js中破绽百出变成进度阻塞的不二秘籍
  • Node.js中制止错误导致的进程阻塞的办法
  • Nodejs中国化学工业进出口总公司解cluster模块的多进度怎么着分享数据难题
  • 深远精通Node.js中的进度管理

本文由美高梅网址发布于关于美高梅,转载请注明出处:调用系统命令的方法分享,js中创建和管理外部进

上一篇:解码二进制数据详解,NodeJS中Buffer模块详解 下一篇:jQuery对html元素取值与赋值的方法,JQUERY获取for
猜你喜欢
热门排行
精彩图文