zoukankan      html  css  js  c++  java
  • exec 和 spawn 的区别

    参考资料:

    最近在用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

  • 相关阅读:
    ASP.NET ZERO 学习 JTable的ChildTable用法
    ASP.NET ZERO Core Application 学习笔记
    uploadify ASP.net 使用笔记
    金额的加减乘除运算
    利用autoit自动关闭指定标题窗口
    Struts2源代码解读之Action调用
    利用btrace工具监控在线运行java程序
    自己实现的简单MVC框架(类似Struts2+Spring)
    简单实用后台任务执行框架(Struts2+Spring+AJAX前端web界面可以获取进度)
    mybatis源代码分析:mybatis延迟加载机制改进
  • 原文地址:https://www.cnblogs.com/xiaoniuzai/p/6889164.html
Copyright © 2011-2022 走看看