exec函数_Node.js中child_process模块中spawn与exec的异同比较

69f31b96d2dc61b3bf618289613738e5.png

Node.js基于事件驱动来处理并发,它本身是以单线程模式运行的。Node.js通过child_process开启子进程执行指定程序。主要包括4个异步进程函数(spawn,exec,execFile,fork)和3个同步进程函数(spawnSync,execFileSync,execSync)。一般我们比较常用的是spawn和exec这两个方法。其中异步进程函数spawn是最基本的创建子进程的函数,其他三个异步函数都是对spawn不同程度的封装。spawn只能运行指定的程序,参数需要在列表中给出,而exec可以直接运行复杂的命令。
默认情况下,stdinstdoutstderr 的管道在父 Node.js 进程和衍生的子进程之间建立。这些管道具有有限的(与平台相关)容量。 如果子进程在没有捕获输出的情况下写入超出该限制的 stdout,则子进程将阻塞等待管道缓冲区接受更多的数据。 这与 shell 中的管道行为相同。 如果不需要输出,则使用 { stdio: 'ignore' } child_process.spawn方法异步地衍生子进程,并且不阻塞 Node.js 事件循环。而child_process.spawnSync方法则以同步的方式提供等效功能,但会阻止事件循环直到衍生的进程退出或终止。
为方便起见,child_process模块提供了child_process.spawn()child_process.spawnSync()的一些同步和异步的替代方法。注意,这些替代方法中的每一个都是基于child_process.spawn()child_process.spawnSync()实现的。

  1. child_process.exec():衍生一个 shell 并在该 shell 中运行命令,当完成时则将stdoutstderr 传给回调函数。
  2. child_process.execFile():类似于 child_process.exec(),除了它默认会直接衍生命令且不首先衍生 shell。
  3. child_process.fork():衍生一个新的 Node.js 进程,并通过建立 IPC 通信通道来调用指定的模块,该通道允许在父进程与子进程之间发送消。
  4. child_process.execSync()child_process.exec() 的同步版本,会阻塞 Node.js 事件循环。
  5. child_process.execFileSync()child_process.execFile() 的同步版本,会阻塞 Node.js 事件循环。

对于某些用例,例如自动化的 shell 脚本,同步的方法可能更方便。 但是在大多数情况下,同步的方法会对性能产生重大影响,因为它会停止事件循环直到衍生的进程完成。

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

const { spawn } = require('child_process');
const ls = spawn('ls', ['-lh', '/usr']);

ls.stdout.on('data', (data) => {
  console.log(`stdout: ${data}`);
});

ls.stderr.on('data', (data) => {
  console.log(`stderr: ${data}`);
});

ls.on('close', (code) => {
  console.log(`子进程退出码:${code}`);
});

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

const { exec } = require('child_process');
exec('cat *.js missing_file | wc -l', (error, stdout, stderr) => {
  if (error) {
    console.error(`执行出错: ${error}`);
    return;
  }
  console.log(`stdout: ${stdout}`);
  console.log(`stderr: ${stderr}`);
});

spawn与exec的相同点

1、都用于开一个子进程执行指定命令。

2、都可以自定义子进程的运行环境。

3、都返回一个ChildProcess对象,所以他们都可以取得子进程的标准输入流、标准输出流和标准错误流。

spawn与exec的不同点

1、接受参数的方式:spawn使用了参数数组,而exec则直接接在命令后。

比如要运行 du -sh /disk1 命令, 使用spawn函数需要写成spawn('du', ['-sh ', '/disk1']),而使用exec函数时,可以直接写成exec('du -sh /disk1')。exec是会先进行Shell语法解析,因此用exec函数可以更方便的使用复杂的Shell命令,包括管道、重定向等。

2、子进程返回给Node的数据量:spawn没有限制子进程可以返回给Node的数据大小,而exec则在options配置对象中有maxBuffer参数限制,且默认为200K,如果超出,那么子进程将会被杀死,并报错:Error:maxBuffer exceeded,虽然可以手动调大maxBuffer参数,但是并不被推荐。由此可窥见一番Node.js设置这两个API时的部分本意,spawn应用来运行返回大量数据的子进程,如图像处理,文件读取等。而exec则应用来运行只返回少量返回值的子进程,如只返回一个状态码。

3、exec方法相比spawn方法,多提供了一个回调函数,可以更便捷得获取子进程输出。这与从返回的ChildProcess对象的stdout或stderr监听data事件来获得输出的区别是: data事件的方式,会在子进程一有数据时就触发,并把数据返回给Node。而回调函数,则会先将数据缓存在内存中(数据量小于maxBuffer参数),等待子进程运行完毕后,再调用回调函数,并把最终数据交给回调函数。

打赏 ⁽⁽ଘ(ˊᵕˋ)ଓ⁾⁾

81e9812b8179fe48bf02032400154c44.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值