可以独立读取每个stdout刷新的stringforms在node.js中的subprocess

我有一个这样的程序:

#include <stdio.h> int main(int argc, char *argv[]) { for(int i = 0; i<3; i++){ printf("Cstdout:%d ", i); fflush(stdout); fprintf(stderr, "Cstderr:%d ", i); fflush(stderr); } return 0; } 

该程序的输出是: Cstdout:0 Cstderr:0 Cstdout:1 Cstderr:1 Cstdout:2 Cstderr:2

我想用这样的node.js脚本来处理它的输出:

 var spawn = require('child_process').spawn, ls = spawn('./io'); var Jstdout = 0, Jstderr = 0; ls.stdout.on('data', function (data) { console.log('Jstdout:' + Jstdout + ' ' + data); ++Jstdout; }); ls.stderr.on('data', function (data) { console.log('Jstderr:' + Jstderr + ' ' + data); ++Jstderr; }); ls.on('close', function (code) { console.log('child process exited with code ' + code); }); 

这个脚本的输出是:

Jstdout:0 Cstdout:0 Cstdout:1 Cstdout:

Jstderr:0 Cstderr:0 Cstderr:1 Cstderr:2

subprocess用代码0退出

但是我想要这样的东西:

Jstdout:0 Cstdout:0

Jstderr:0 Cstderr:0

Jstdout:1 Cstdout:1

Jstderr:1 Cstderr:1

投标:2投标:2

Jstderr:2 Cstderr:2

subprocess用代码0退出


我猜你的C ++程序比你的node.js可以更快地读取缓冲区。 如果让你的孩子在每次迭代之后等待大约100ms,会发生什么? – Dirk Horsten

Dirk Horsten是真的:

 #include <stdio.h> #include <unistd.h> int main(int argc, char *argv[]) { for(int i = 0; i<3; i++){ printf("Cstdout:%d ", i); fflush(stdout); sleep (1); fprintf(stderr, "Cstderr:%d ", i); fflush(stderr); sleep (1); } return 0; } 

这段代码将产生我想要的输出,但是我想格式化我没有编写的程序的输出,而且我不能容易地在这些程序中放入延迟。

例如,我想为valgrind的输出着色,但valgrind的输出同时使用stdout和stderr。 当我试图做的文字块的位置得到改变。

在下一个脚本中,我尝试着将输出颜色设为蓝色,并输出valgrind红色:

 var spawn = require('child_process').spawn, ls = spawn('valgrind', [process.argv[2]]); ls.stdout.on('data', function (data) { console.log('\033[1;34m' + data + '\033[0m'); }); ls.stderr.on('data', function (data) { console.log('\033[1;31m' + data + '\033[0m'); }); ls.on('close', function (code) { console.log('child process exited with code ' + code); }); 

这是不可能的,至less使用传统的手段。

subprocess输出通过pipe道接收。 Pipe是OS提供的对象。 内部它有一个缓冲区; pipe道上的每个write()都附加到缓冲区。 个别块的边界不会被保留下来 – 如果作者足够快,在读者有机会读取任何东西之前,它将设法排列多个项目。 读者将收到目前可用的任何数据; 如果多个块被缓冲,它可以一次全部接收它们。

当然,这个问题通过pipe道交换信息有点困难。 为了使拆分连接的消息成为可能,必须在消息结束处指示一些指示(例如:换行符终止消息[ 某个nodejs上下文 ])。

关于冲洗的说明。 在C FILE对象中有一个自己的缓冲区。 刷新将缓冲区内容传送到底层操作系统对象,即刷新转换为在pipe道上写入。