09-子进程
20.8 子进程
child_process 模块可以让应用执行其他程序,不论是Node程序、可执行程序、还是由其他语言编写的脚本。讨论管理子进程的所有细节已经超出了本书的范围,不过这里还是会用一个简单的例子来演示子进程的用法。
child_process 模块对外主要暴露了三个函数:exec、execFile、和fork。与fs一样,这三个函数都有各自的同步版本( execSync 、 execFileSync 和 forkSync )。exec和execFile可以运行任何操作系统支持的可执行程序。exec会调用一个shell(它位于操作系统命令行底层,如果可以通过命令行来运行一个程序,那么exec也能运行它)。 execFile 允许直接运行可执行程序,这种方式能略微优化内存和资源的使用,但用的时候要格外小心。最后,fork允许执行另一个Node脚本(这也通过exec来完成)。
fork会启动一个独立的Node引擎,所以它的资源开销与exec一样。不过, `fork` 可以进行一些进程间通信的设置。详情见官方文档(http://bit.ly/1PxcnL9)。
由于exec是最常见的,也最好用,所以本章会一直使用它。
为了演示这个功能,下例中会执行dir命令,它可以显示一个目录列表(熟悉Unix的读者可能对ls更熟悉,在大部分Unix系统中,dir是ls的别名):
const exec = require('child_process').exec;
exec('dir', function(err, stdout, stderr) {
if(err) return console.error('Error executing "dir"');
stdout = stdout.toString(); // 把Buffer转化成 string
console.log(stdout);
stderr = stderr.toString();
if(stderr !== '') {
console.error('error:');
console.error(stderr);
}
});
因为exec会调用shell,所以不需要提供dir这个可执行文件的路径。如果需要调用一个不能从系统shell中直接访问的特殊程序,就需要提供可执行文件的全路径。
被调用的callback会接收两个Buffer对象,stdout(程序的正常输出)和stderr(错误输出,如果有的话)。在本例中,由于并不想要输出任何内容到stderr,所以在打印输出之前先检查一下是否有错。
exec会接收一个可选的options对象,这可以由开发人员指定一些诸如工作目录、环境变量等信息。详情参见官方文档。
注意看这里是如何引入exec的。此处没有使用 `const child_` `process=require('child_process')` 来引入c `hild_process` ,然后以 `child_process.exec` 来调用 `exec` ,而是直接给 `exec` 定义了别名。两种方法都能用,但是上面所用的方法更为常见。
fork会启动一个独立的Node引擎,所以它的资源开销与exec一样。不过, `fork` 可以进行一些进程间通信的设置。详情见官方文档(http://bit.ly/1PxcnL9)。