繁体   English   中英

没有从nodejs生成的进程接收stdout

[英]Not receiving stdout from nodejs spawned process

我正在尝试让nodejs冒险 ,一个旧的基于文本的游戏进行交互。 这个想法是将冒险作为一个子进程开放,然后通过写入stdin并在stdout上放置一个事件监听器来玩游戏。

游戏开始时,会打印出一个初始值:

欢迎来到冒险! 你想要指示吗?

所以为了说明我的问题,我有一个nodejs + express实例:

var childProcess = require('child_process');
var spawn = childProcess.spawn;
var child = spawn('adventure');

console.log("spawned: " + child.pid);

child.stdout.on('data', function(data) {
  console.log("Child data: " + data);
});
child.on('error', function () {
  console.log("Failed to start child.");
});
child.on('close', function (code) {
  console.log('Child process exited with code ' + code);
});
child.stdout.on('end', function () {
  console.log('Finished collecting data chunks.');
});

但是当我启动服务器时,游戏中的文本没有到达事件监听器:

spawned: 24250

这就是我得到的所有输出。 永远不会调用child.stdout.on甚至是监听器。 为什么游戏中的初始线不会被拾取?

如果我将以下行附加到上面的javascript块,则程序输出立即出现。 所以adventure运行,我现在可以强制它触发child.stdout.on事件监听器...但这也结束了子进程,这违背了读写它的目的。

...
child.stdout.on('end', function () {
  console.log('Finished collecting data chunks.');
});
child.stdin.end();

现在的输出是:

spawned: 28778  
Child data:
Welcome to Adventure!!  Would you like instructions?
user closed input stream, quitting...

Finished collecting data chunks.
Child process exited with code 0

我确信这对我来说是一个微不足道的疏忽,我感谢任何有助于解决这个问题的人。

经过Nodejs文档几次之后,我确信自己错过了一些非常大的东西,或者spawn命令无法正常工作。 所以我创建了一个github问题

答案立即发布:如果您想快速访问,子进程无法缓冲输出。

所以要实现我最初寻找的东西:

var childProcess = require('child_process');
var spawn = childProcess.spawn;
var child = spawn('unbuffer', 'adventure');

console.log("spawned: " + child.pid);

child.stdout.on('data', function(data) {
  console.log("Child data: " + data);
});
child.on('error', function () {
  console.log("Failed to start child.");
});
child.on('close', function (code) {
  console.log('Child process exited with code ' + code);
});
child.stdout.on('end', function () {
  console.log('Finished collecting data chunks.');
});

功能差异在于使用unbuffer ,这是一个禁用输出缓冲的命令。

为什么游戏中的初始线不会被拾取?

我在从node.js调用编译的C ++程序的项目上遇到了同样的问题。 我意识到问题出在编译的C ++程序中:我没有刷新stdout流。 添加fflush(stdout); 印刷线后解决了问题。 希望你仍然可以访问游戏的来源!

传递的data是缓冲区类型,而不是字符串。 因此,您需要一个解码器来读取该缓冲区,然后进行日志记录。

这是怎么做的。

var StringDecoder = require('string_decoder').StringDecoder;
var decoder = new StringDecoder('utf8');

child.stdout.on('data', function (data) {
    var message = decoder.write(data);
    console.log(message.trim());
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM