参考资料:

最近在用nodejs 的child_process 模块调用系统的shell脚本,但是发现遇到一些问题

  1. child_process.exec 方法调用shell脚本发现内容过长会抛错 Error: maxBuffer exceeded(和options.maxBuffer有关)
  2. child_process.spawn 方法调用shell脚本发现控制台无法监听用户的输入(和options. stdio 设置有关)
  3. nodejs 调用 shell 后,shell里面的命令找不到(和options.env有关)
  4. nodejs 如何传入 env 到shell里(和options.env有关)

spawn 和 exec 的区别

总体来说 spawn 返回一个stream,exec返回一个buffer

child_process.spawn 返回一个有输出流和错误的流的对象,你可以监听它们从而获取数据,输出流有数据和结束事件,child_process.spawn 适合用在处理大量数据返回的场景中,图片处理,读二进制数据等等。

child_process.spawn是一个异步的异步函数,怎么解释呢?child_process.spawn 在执行时就会返回数据,而不是等到数据都处理好了再一次返回。

child_process.exec 一次性返回输出执行结果内容,默认的buffer大小为200kb,如果exec返回的内容超过 200kb则会返回一个错误:Error maxBuffer execeded,你可以通过设置options buffer的size来扩大 buffer 的大小。

child_process.exec 是一个同步的异步方法,这个意思是,虽然方法体本身是异步的,但是它要等 child process 执行完成后,再把返回数据一口气返回给回调方法。如果返回内容超过了设置的buffer size,则会返回一个maxBuffer exceeded 错误。

options.stdio

options.stdio 选项用于配置子进程与父进程之间建立的管道。 默认情况下,子进程的 stdin、 stdout 和 stderr 会重定向到 ChildProcess 对象上相应的 child.stdinchild.stdoutchild.stderr 流。 这等同于将 options.stdio 设为 ['pipe', 'pipe', 'pipe']。

这个配置不一定是数组,也可以是字符串,

  • pipe == [‘pipe', 'pipe', 'pipe']
  • ignore == ['ignore', 'ignore', 'ignore']
  • inherit == [process.stdin, process.stdout, process.stderr] 流会定向到你系统的bash 环境中,nodejs不再接管错误、数据的处理
let ls = spawn('ls', ['-al'], {
stdio: ['pipe', 'pipe', 'pipe']
}); 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}`);
});

这种情况下,子进程的数据会返回给父进程,也就是nodejs,然后你可以监听流的输出。

设置 stdio 为 ‘inherit’

let ls = spawn('ls', ['-al'], {
stdio: ['inherit', 'inherit', 'inherit']
}); ls.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});

会抛出错误,

ls.stdout.on('data', (data) => {
^
TypeError: Cannot read property 'on' of null

但是你在控制台应该可以看到数据,这个数据是bash执行的结果

传入shell的环境变量

使用 options.env 可以传入变量,在 shell中可以直接使用。

test_shell.js

#! /bin/bash

echo $NAME

test_child_process.js

let spawn = require("child_process").spawn;

let options = {
stdio: 'inherit',
env: Object.assign({NAME: "cowboy"}, process.env)
} spawn('sh', ['./test_shell.sh'], options);

输出

cowboy

exec 和 spawn 的区别的更多相关文章

  1. Nodejs exec和spawn的区别

    spawn child_process.spaen会返回一个带有stdout和stderr流的对象.你可以通过stdout流来读取子进程返回给Node.js的数据. stdout拥有’data’,’e ...

  2. SQL Server 中 EXEC 与 SP_EXECUTESQL 的区别

    SQL Server 中 EXEC 与 SP_EXECUTESQL 的区别 MSSQL为我们提供了两种动态执行SQL语句的命令,分别是 EXEC 和 SP_EXECUTESQL ,我们先来看一下两种方 ...

  3. js正则表达test、exec和match的区别

    test的用法和exec一致,只不过返回值是 true false. 以前用js很少用到js的正则表达式,即使用到了,也是诸如邮件名称之类的判断,网上代码很多,很少有研究,拿来即用. 最近开发遇到一些 ...

  4. js正则表达式中test,exec,match方法的区别说明

    js正则表达式中test,exec,match方法的区别说明 test test 返回 Boolean,查找对应的字符串中是否存在模式.var str = "1a1b1c";var ...

  5. 【Sqlserver】SqlServer中EXEC 与 SP_EXECUTESQL的 区别

    MSSQL为我们提供了两种动态执行SQL语句的命令,分别是 EXEC 和 SP_EXECUTESQL ,我们先来看一下两种方式的用法. 先建立一个表,并添加一些数据来进行演示: CREATE TABL ...

  6. 转转转---js正则表达exec与match的区别说明

    正则表达式对象有两个定义方式:: 1.第一种定义: new RegExp(pattern, attributes);如var reg = new RegExp("abc",&quo ...

  7. shell中sh, exec, source, fork, ./的区别

    shell中sh, exec, source, fork, ./的区别 1,sh sh test.sh ​ sh是通过创建子进程(subshell)去执行脚本,父进程无法使用子进程中的变量,而子进程对 ...

  8. -exec 与 xargs 的区别

    实地在shell里执行下如下命令就知道区别了: $ find -type f -exec echo {} \; 很明显,exec是对每个找到的文件执行一次命令.从这里可以看出exec的缺点是每处理一个 ...

  9. js正则表达式中test,exec,match方法的区别

    test test 返回 Boolean,查找对应的字符串中是否存在模式.var str = "1a1b1c";var reg = new RegExp("1." ...

随机推荐

  1. Android组件间通信库EventBus学习

    项目地址:   https://github.com/greenrobot/EventBus EventBus主要特点 1. 事件订阅函数不是基于注解(Annotation)的,而是基于命名约定的,在 ...

  2. 把握linux内核设计思想(二):硬中断及中断处理

    [版权声明:尊重原创.转载请保留出处:blog.csdn.net/shallnet,文章仅供学习交流,请勿用于商业用途] 操作系统负责管理硬件设备.为了使系统和硬件设备的协同工作不减少机器性能.系统和 ...

  3. 为什么阿里巴巴不建议在for循环中使用"+"进行字符串拼接

    字符串,是Java中最常用的一个数据类型了.关于字符串的知识,作者已经发表过几篇文章介绍过很多,如: Java 7 源码学习系列(一)--String 该如何创建字符串,使用" " ...

  4. 完好用户体验: 活用window.location与window.open解决页面跳转问题

    原文地址: JavaScript Redirects and window.open原文日期: 2014年08月27日翻译日期: 2014年08月31日翻译人员: 铁锚 (译者注: 本文解决的是按 C ...

  5. 2018年EMUI系统能力分论坛来啦

    为鼓励开发者创新,挖掘前沿创新能力的应用及服务,帮开发者打造爆款应用的同时丰富终端消费者的用户体验,由设立10亿激励基金耀星计划扶持的华为创新竞赛平台即将开启. 竞赛平台将滚动推出AI.HAG.AR. ...

  6. TP 自动验证规则

    #自动验证 protected $_validate=array( #参数最后代表1 表示必须验证,0表示当这个字段存在的时候验证 array('username','require','账号不能为空 ...

  7. Oracle学习第三篇—多行函数

    0 order by asc/desc 默认升序 order by 列的名字|表达式|别名|序号 把空放在后边:order by desc nulls last 1分组函数--会自动滤空值 count ...

  8. CI学习总结

    1.CI自定义配置文件: 如:config/test.php <?php $config['test']['good'] = array('aa','bb'); 在控制器中这样调用: <? ...

  9. Android - 使用messager实现进程间通信(服务器端→客户端,客户端→服务器端双向)

    之前看了一篇,然后不自己动手肯定是不行的,然后自己又写了一遍. 背景: 一般使用messenger进行进程间通信的时候,我们只能进行单方向通信.但是有没有办法让服务器端和客户端进行双向通信呢? 解决思 ...

  10. 【BZOJ4908】[BeiJing2017]开车 分块

    [BZOJ4908][BeiJing2017]开车 Description 你有n辆车,分别a1, a2, ..., an位置和n个加油站,分别在b1, b2, ... ,bn .每个加油站只能支持一 ...