【问题标题】:spawned child_process stdout to 'readline' without buffering in node?将 child_process stdout 生成到“readline”而不在节点中缓冲?
【发布时间】:2017-09-09 21:08:00
【问题描述】:

当我从命令行运行 myProgram 时,输出会在生成时实时显示。当我像这样从节点生成它时,stdout 会缓冲并一次输出一大块。

const bat = require('child_process').spawn('myProgram', []);
bat.stdout.setEncoding('utf8');
bat.stdout.on('data', console.log);

如何告诉 child_process 不要缓冲标准输出?还是将缓冲区大小设置得更小?

下一次尝试:

const spawn = require('child_process').spawn;

var options = {
    stdio: ["ignore", process.stdout, "ignore"]
};

const bat = spawn('myProgram', [], options);

const rl = require('readline').createInterface({
  input: process.stdout
});

rl.on('line', function(line) {
    console.log(line);
});

这会将process.stdout 打印到终端,但readline 不会获取数据,即使documentation says process.stdout“...是双工流...”

【问题讨论】:

  • 尝试用require('child_process').spawn('myProgram', { stdio: ["ignore", process.stdout, "ignore"] })替换整个代码块
  • 谢谢 - 可以无缓冲地传递给控制台。我真正需要做的是流入'readline'。可以无缓冲地完成吗?
  • 具体来说,stdio 参数可以是“tty、文件、套接字或管道”流。如何创建一个可以在那里工作的流,并让 readline 在它到达后立即吐出一行而不是等待一个大缓冲区?

标签: node.js


【解决方案1】:

也许让spawn 创建一个新的标准输出流并将其传递给readline 是最简单的:

const bat = spawn('myProgram');
const rl  = require('readline').createInterface({ input: bat.stdout });

编辑:好的,问题不在于 Node,而在于 C/C++ 标准输出缓冲。如果你通过cat 管道输出程序的输出,它也不会在生成时显示输出:

./main | cat

既然您有代码,最简单的解决方法是禁用stdout 上的缓冲:

#include <stdio.h>

setbuf(stdout, NULL);

或者,在每个 printf() 之后调用 fflush(stdout)。

【讨论】:

  • 'readline' 的输出在缓冲后一次出现多行。每次从 myProgram 出来时,如何强制“readline”发出一行?
  • 您使用的是什么操作系统?我测试了各种输出行和“睡眠”的程序,每行在生成的那一刻被readline拾取。当您通过类似cat 的方式输出正在运行的程序的输出时会发生什么?当程序连接到管道而不是终端时,程序的输出可能会表现不同。
  • OSX 10.11.6 / 节点 5.0.0
  • 您要运行的程序是什么?你能用其他程序重现这个问题吗? (我在基本相同的操作系统上,所以很容易测试)
  • 这是一个来自 NITE 库的示例 c++ 程序(检测来自 kinect 相机的手势)。它将更新的坐标打印到控制台,我正在尝试将这些坐标流式传输到带有节点的 websocket 广播器。 github.com/jbeuckm/kinect_websocket_server
【解决方案2】:

这对我有用,希望对你有帮助

  var spawn = require('child_process').spawn;
   const {chunksToLinesAsync, chomp} = require('@rauschma/stringio');

   var options = {
    stdio: ["ignore", "pipe", process.stderr]
};
   console.log("Here is the complete output of the program: ");
   
   var child = spawn(i, [],options);
   echoReadable(child.stdout); // (B)

  console.log('### DONE');

  async function echoReadable(readable) {
    for await (const line of chunksToLinesAsync(readable)) { // (C)
      console.log('LINE: '+chomp(line))
    }
  }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-03
    相关资源
    最近更新 更多