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

cta*_*tag 9 io spawn child-process node.js

我正在尝试让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.');
});
Run Code Online (Sandbox Code Playgroud)

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

spawned: 24250
Run Code Online (Sandbox Code Playgroud)

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

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

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

现在的输出是:

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
Run Code Online (Sandbox Code Playgroud)

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

cta*_*tag 6

在再次浏览了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.');
});
Run Code Online (Sandbox Code Playgroud)

由于使用的功能不同unbuffer,该命令禁用了输出缓冲。

  • 就我而言,我的系统上没有“unbuffer”命令,但“spawn”的“options”参数的“{shell: true}”选项生成了输出。Linux 上还有“stdbuf”命令来控制缓冲,但在我的情况下它不会改变任何东西。(我从“openjdk”包生成“java”编译器。) (2认同)

小智 6

为什么游戏中的第一句台词没有被拾取?

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

  • 事实证明,缓冲发生在 Node.js 端,但缓冲是根本问题。感谢您抽出时间来回答。 (2认同)