参考资料:

最近在用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. 【Python】向函数传递任意数量的实参

    传递任意数量的实参 有时候,你预先不知道函数需要接受多少个实参,好在Python允许函数从调用语句中收集任意数量的实参 def get_letter(*letters): for i in lette ...

  2. 何为SLAM

    名词解释:        SLAM (simultaneous localization and mapping),也称为CML (Concurrent Mapping and Localizatio ...

  3. python:如何判断字符串中的内容是否都为数字并且把字符串转换为数字

    使用str.isdigit();有两种使用方法 str.isdigit('12345') =====>True str.isdigit('aaaaa')======>False 或者 '1 ...

  4. LeetCode Hash Table 3. Longest Substring Without Repeating Characters

    HashMap的应用可以提高查找的速度,键key,值value的使用拜托了传统数组的遍历查找方式,对于判断一个字符或者字符串是否已经存在的问题可以非常好的解决.而本题需要解决的问题就是判断新遍历到的字 ...

  5. [读书笔记] learn python the hard way书中 有关powershell 的一些小问题

    ex46中,创建自己的python,  当你激活环境时 .\.venvs\lpthw\ Scripts\activate 会报一个错误 此时需要以管理员身份运行PowerShell,(当前的PS不用关 ...

  6. dede二级导航与二级栏目 ----内容介绍二级导航

    {dede:channelartlist typeid='top'}//如果只需要拿一列,则需要使用row='1'这个属性否则会根据子频道的数目循环输出 <a href="{dede: ...

  7. Inno Setup 使用笔记

    使 用 笔 记https://blog.csdn.net/dongshibo12/article/details/79095971 1.Inno Setup 是什么?Inno Setup 是一个免费的 ...

  8. NUTCH2.3 hadoop2.7.1 hbase1.0.1.1 solr5.2.1部署(二)

     Precondition: hadoop 2.7.1 hbase 1.0.1.1 / hbase 0.98.13 192.168.1.106 ->master 192.168.1.105 ...

  9. WPF实现ScrollViewer滚动到指定控件处

    在前端 UI 开发中,有时,我们会遇到这样的需求:在一个 ScrollViewer 中有很多内容,而我们需要实现在执行某个操作后能够定位到其中指定的控件处:这很像在 HTML 页面中点击一个链接后定位 ...

  10. MySQL CREATE TRIGGER (1)

    CREATE TRIGGER语法 CREATE TRIGGER trigger_name trigger_time trigger_event    ON tbl_name FOR EACH ROW ...